目录
1.后置处理器PostProcessor
后置处理器有三种
BeanDefinitionRegistryPostProcessor: BeanDefinitionRegistry的后置处理器
BeanFactoryPostProcessor :Bean 工厂后置处理器
BeanPostProcessor :Bean 后置处理器
前两个是容器级别的后置处理器,最后一个属于Bean级别的后置处理器。BeanDefinitionRegistryPostProcessor在 Bean 实例化和BeanFactoryPostProcessor 检测开始之前,注册更多的BeanDefinition,除此之外,你还可以修改已注册的 BeanDefinition 信息。在注解的方式启动容器的时候,不管是从参数里面传进来的BeanDefinitionRegistryPostProcessor还是从容器里面获取到已经注册的BeanDefinitionRegistryPostProcessor,都会先于BeanFactoryPostProcessor去执行。用途呢可以在里面去搜索某些第三方的项目里面的Class,然后通过这种方式注入进容器,就可以在容器里面去使用他们了。
@Configuration
public class WXBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
Class<User> userClass = User.class;
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(userClass);
GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanDefinitionBuilder.getRawBeanDefinition();
registry.registerBeanDefinition("user", genericBeanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
BeanPostProcessor 是 Bean 后置处理器接口,里面包含两个方法:postProcessBeforeInitialization 和 postProcessAfterInitialization。前者在 Bean 实例化(不是BeanDefination实例化)前调用,后者则是在实例化后。比如生成一个 Bean 的代理类,就是其子类做的。
2.Aware及其子接口
容器对bean的逻辑本身是无侵入的,因此Bean一般不需要了解容器的状态,但是在某些情况下在bean中需要对容器进行直接的操作。这个时候就需要在bean中设定对容器的感知,这便是Aware接口的作用。
Aware是一个空的接口,能发挥作用的是它的一些实现
例如ApplicationContextAware,在容器创建这个bean的时候将容器本身作为参数传入,获取容器相关的信息
BeanFactoryAware,在容器创建这个bean的时候将BeanFactory本身作为参数传入,获取BeanFactory相关的信息
使用他就是直接实现他的接口即可
3.事件监听器模式
什么是回调函数?简单来说就是调用一个组件的时候,按照组件的定义注册一个我们自己的方法,期待组件在特定的场景下去调用我们注册的方法。
事件源(Evnet Source)
事件监听器(Event Listener)事件监听器需要注册到事件源里面
事件对象(Event Object) 作为事件源与监听器之间得消息传递
Spring里面的事件驱动模型之容器事件
1.事件ApplicationEvent
ContextStoppedEvent:容器停止后出发的事件
ContextRefreshedEvent:容器初始化或者刷新完成后出发的事件
ContextClosedEvent:容器关闭后触发的事件
ContextStartedEvent:容器启动后触发的事件
在Spring4.2之前所有的事件都必须强制继承自ApplicationEvent,在4.2以后Spring提供了一个PayloadApplicationEvent的包装类,就不再强制事件必须继承自ApplicationEvent
2.事件监听器ApplicationListener
SmartApplicationListener可以对监听器进行排序
想要实现事件监听器就需要实现ApplicationListener,或者使用@EventListener,就可以将这个Bean晋升为监听器,使用sayHello方法进行监听,返回值是任意的,如果返回值不是Void,此时的返回值会被当做一个新的事件再次进行发布。
3.事件发布器ApplicationEventPublisher和ApplicationEventMulticaster
ApplicationContext继承了ApplicationEventPublisher,说明ApplicationContext具有事件发布的能力,同时还存在与ApplicationEventPublisher相关的Aware接口ApplicationEventPublisherAware
这个Aware接口上面说过是让Bean可以感知到容器的存在,我们可以在Bean里面通过Aware来获取到ApplicationEventPublisher这个实例(ApplicationContext),然后就可以向容器里面发布自定义的事件,给容器里面注册的自定义的EvnetListener去处理。
ApplicationEventMulticaster:不仅仅具有发布事件的能理,还有添加和删除事件的方法。
SimpleApplicationEventMulticaster里面如果设置了Executor,就支持多线程去发布事件
为什么有两个事件发布的接口?为什么不使用SimpleApplicationEventMulticaster来替换掉ApplicationEventPublisher?
因为想Bean和容器他们就只想发布事件,并不想维护事件,所以Spring对事件源进行了进一步的切割
4.Spring容器 的刷新逻辑
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 刷新容器前的准备工作
prepareRefresh();
// 对于XML来讲特别重要,涉及到BeanDefinition的注册,对于注册来讲仅仅是调用了子类的refreshBeanFactory
//获取到DefaultListableBeanFactory的实例
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 为容器注册必要的系统级别的Bean,例如classLoader beanFactoryPostProcessor
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//允许容器的子类去注册postProcessor
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
//执行容器级别的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//向容器注册Bean级别的后置处理器
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
//初始化国际化配置
initMessageSource();
// Initialize event multicaster for this context.
//初始化事件发布者组件
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 单例Bean初始化之前,预留给子类初始化预留给子类初始化其他特殊bean的口子
onRefresh();
// Check for listener beans and register them.
//向前面时间发布者组件注册监听器
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//设置一些系统级别的服务,实例化所有非懒加载的单例
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//触发初始化完成的回调方法,并发布容器刷新完成的事件给监听者
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
//重置Spring中的内核共用缓存
resetCommonCaches();
contextRefresh.end();
}
}
}