王福强老师的《Spring揭秘》读后感-IOC容器之ApplicationContext相关
回忆一下ApplicationContext与BeanFactory的关系图
接下来讲述AppliactionContext实现的其他的接口与协议
Spring框架内部使用Resource接口作为所有资源的抽象和访问接口。 其中 classPathResource的一个特定类型的实现,代表的是位于Classpath中的实现。如果需要实现自定义的Resource,可以直接扩展AbstractResource抽象类,然后根据当前具体特征,覆盖相应的方法就可以了
ResourceLoader 用来查找和定位资源 ,该接口中最主要的是 Resource getResource(String location) 方法
实现类之一:
DefaultResourceLoader 定位资源规则:
1.查找[Classpath:]打开尝试构造ClasspathResource类资源并返回
2.通过URL定位资源
实现类之二:
FileSysetmResourceLoader 通过覆写了getResourceBPath()方法,使之从我恩件系统加载资源并以FileSystemResource类型返回。
ResourceLoader的扩展实现:ResourcePatternResolver :引入了新的协议前缀[ClassPath*:],同时支持批量查找Resource资源
Resource和ResourceLoader的关系 |
由于ApplicationContext实现过了ResourceLoader接口,所以ApplicationContext的任何实现都可以看作是一个ResourceLoader甚至ResourcePatternResolver,而这就是ApplicationContext支持Spring内统一资源加载策略的真相
tips:[ApplicationContext类型的容器可以自动识别Aware接口]
国际化信息支持:
Java中的国际化信息处理,主要设计两个类:Locale和Resourcebundle
Spring在Java的国际化支持的基础上,进一步抽象了国际化信息的访问接口即:MessageSource
ApplicationConetxt也实现了该接口,所以ApplicationContext现在也是一个MessageSource
在默认情况下,ApplicationContext将委派容器中的一个名称为messageSource的MessageSource接口实现类来完成该接口应该完成的职责,如果找不到,ApplicationContext内部会默认实例化一个不含任何内容的StaticMessageSource实例。
--可用的MessageSource实现:
1.StaticMessageSource 多用于测试
2.ResourceBundleMessageSource 基于标准的ResourceBundle实现的
3.ReloadableResourceBundleMessageSource,该类可以通过是设置cacheSeconds属性可以指定时间段,以定期刷新并检查底层的properties资源文件是否有变更。
ApplicationContext启动的时候,会自动识别容器中类型为MessageSourceAware的bean定义并将资深作为MessageSource注入相应对象实例中。
容器内部事件发布
Java提供了实现自定义时间发布的基础类:EventObject 和 EventListener 接口 所有的自定义时间类型可以通过扩展EventObject来实现,而事件的监听则扩展自EventListerner。通常情况下,我们会有一个时间发布者(EventPublisher)它本身作为事件源,会在合适的时间点,将相应事件发布给对应的事件监听器
ApplicationContext容器内部允许以ApplicationContextEvent的形式发布事件,容器内注册的ApplicationListener类型的bean会被ApplicationContext容器自动识别,他们负责监听容器内发布的所有ApplicationEvent类型的事件
Spring容器内默认提供的三个ApplicationEvent事件的实现:
ContextClosedEvent 容器即将关闭的时候发布的事件类型
ContextRefreshEvent 在初始化或者刷新的时候发布的事件类型
RequestHandledEvent Web请求处理后发布的事件,它有一个子类ServletRequestHandledEvent提供特定Servlet相关事件
ApplicationContext接口定义还继承了ApplicationEventPublisher接口,所以呢。ApplicationContext容器现在担当的就是时间发布者的角色。
在具体的逻辑处理中ApplicationContext把事件发布的功能全部委托给了ApplicationEventMulticaster来做,默认使用了SyncTaskExecutor进行事件发布,这些事件是同步顺序发布的。
ApplicationContext容器内的事件发布机制,主要用于单一容器内的简单消息通知和处理,并不适合分布式。多进程。多容器之间的时间通知。[虽然可以通过Spring的Remoting支持,但是相对与直接使用第三方技术,实现更为麻烦]
--要让我们的业务类支持容器内的事件发布,需要它又有ApplicationEventPublisher的事件发布支持,所以,需要为其注入publisher实例..两种方式
1.使用ApplicationEventPublisherAware接口
2.使用ApplicationContextAware接口[这个就不需要在说为什么了吧...]
Spring支持基于注解的依赖注入 [为什么AutoWired等注解可以生效]
我们可以提供一个Spring的Ioc容器使用的BeanPostProcessor自定义实现,让这个bean在实例化的过程中,来检查当前对象是否有@autowired标注的依赖需要注入...Spring已经提供了该实现:[AutowiredAnnotationBeanPostProcessor]
@Autowired是基于ByType
---使用JSR250标注依赖注入关系
@Resource是基于ByName
@postConstruct 和 @PreDestory
Spring 支持JSR250的BeanPostProcessor 实现类是 CommonAnnotationBeanPostProcessor
组件扫描<context:component-scan>的name-generator属性可以制定我们自己的BeanNameGenerator实现类来替换掉默认的BeanNameGenerator,也可以改变默认的Bean定义的名称生成规则。