王福强老师的《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资源

王福强老师的《Spring揭秘》读后感-IOC容器之ApplicationContext相关

                                                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定义的名称生成规则。