IOC的扩展点之灵活运用Spring框架
这里感谢 CSDN 的原博客: https://blog.csdn.net/qq_41737716/article/details/84990660
1、初始化ApplicationContext
回忆一下ApplicationContext
初始化过程中refresh这个方法:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从
//子类的refreshBeanFactory()方法启动
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//为BeanFactory配置容器特性,例如类加载器、事件处理器等
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//为容器的某些子类指定特殊的BeanPost事件处理器
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//调用所有注册的BeanFactoryPostProcessor的Bean
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//为BeanFactory注册BeanPost事件处理器.
//BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//初始化信息源,和国际化相关.
initMessageSource();
// Initialize event multicaster for this context.
//初始化容器事件传播器.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//调用子类的某些特殊Bean初始化方法
onRefresh();
// Check for listener beans and register them.
//为事件传播器注册事件监听器.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//初始化所有剩余的单例Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//初始化容器的生命周期事件处理器,并发布容器的生命周期事件
finishRefresh();
}
//异常处理,略...
}
}
由前面第一篇文章中介绍的,初始化开头调用了ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 方法,此时将所有的Bean转换成Bean信息封装类BeanDefinition对象注册进beanFactory,第二篇文章中介绍,初始化末尾调用了finishBeanFactoryInitialization(beanFactory); 方法进行所有单例Bean的初始化,那么refresh中 中间还有那么多的方法,是干什么用的呢?
(这里只提与自定义扩展有关的需要关注的方法):
- invokeBeanFactoryPostProcessors(beanFactory):调用所有实现了
BeanFactoryPostProcessor
接口的Bean的一个回调方法。 - registerBeanPostProcessors(beanFactory):注册所有实现了
BeanPostProcessor
接口的Bean,注意这里仅仅是注册,在Bean的初始化时会遍历所有注册好的Processor调用回调方法。 - initApplicationEventMulticaster():初始化监听事件的容器,此处可自定义,如无定义使用默认监听器容器。顾名思义,监听器容器就是用来存放监听器,并且可以回调监听器的方法。
- registerListeners():注册所有的监听器,也就是将所有实现
ApplicationListener
的Bean注册进上面第三步的监听器容器。 - finishRefresh():在IOC容器初始化结束之后,会调用实现了Lifecycle的Bean的start()方法。并且发布一个事件publishEvent(newContextRefreshedEvent(this)) 给监听器容器,监听器容器会通知所有监听器,并回调执行监听器方法(传入event)。
根据上面5个步骤,我们大致可以将扩展点分为3点:
- BeanFactory级别的回调方法
- Bean级别的回调方法
- 监听器事件驱动式回调
参考《Spring源码深度解析》:BeanFactoryPostProcessor可以对Bean的定义(配置元数据)进行处理。也就是说SpringIOC容器允许BeanFactoryPostProcessor在容器实际实例化任何其他Bean之前读取配置元数据,并有可能修改它。如果你愿意,你可以配置多个BeanFactoryPostProcessor。
如果你想改变实际的Bean实例,那么你最好使用BeanPostProcessor。同样地,BeanFactoryPostProcessor的作用域范围是容器级的。
2、BeanFactory的后处理
2.1、BeanFactoryPostProcessor典型应用
参考《Spring源码深度解析》:BeanFactoryPostProcessor典型应用PropertyPlaceholderConfigurer
<bean id="message" class="distConfig.HelloMessage">
<property name="mes">
<value>${bean.message}</value>
</property>
</bean>
<bean id="mesHandler" class="org.Springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<list>
<value>config/bean.properties</value>
</list>
</property>
</bean>
在bean.properties文件中配置如下:
bean.message=Hi,can you find me?
其中,PropertyPlaceholderConfigurer
这个类实现了BeanFactoryPostProcessor
接口,所以在refresh的时序上来看,它会在载入、注册所有Bean的配置信息之后,去执行BeanFactoryPostProcessor
接口的postProcessBeanFactory方法,此类的这个方法就是将占位符进行解析,注意此类location属性正是包含了配置文件,从而达到从配置文件中替换bean中的占位符的效果。
2.2、BeanFactoryPostProcessor注册与调用过程
回到refresh的时序中,假设现在已经加载注册完所有Bean的配置信息了,接着调用invokeBeanFactoryPostProcessors(beanFactory) 方法:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//调用实现BeanFactoryPostProcessor接口的Bean的postProcessBeanFactory方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
委派PostProcessorRegistrationDelegate
类去执行相应回调方法:
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
//首先处理已经注册了的BeanFactoryPostProcessor(硬编码)
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//先处理BeanDefinitionRegistryPostProcessor,其是BeanFactoryPostProcessor子类
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//这里执行BeanDefinitionRegistryPostProcessor的回调方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
//剩余不是BeanDefinitionRegistryPostProcessor的加入此List
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//这里从beanFactory从寻找BeanDefinitionRegistryPostProcessor类型的Bean
//先执行的是实现了PriorityOrdered接口的那些回调
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//执行BeanDefinitionRegistryPostProcessor的回调方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
//寻找beanFactory中BeanDefinitionRegistryPostProcessor
//第二执行的是实现了Ordered接口的那些回调
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//执行BeanDefinitionRegistryPostProcessor的回调方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
//寻找beanFactory中BeanDefinitionRegistryPostProcessor
//第三执行的是其他普通的回调
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
//排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//执行BeanDefinitionRegistryPostProcessor的回调方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//执行所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//执行所有其他的BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
//寻找beanFactory中所有实现了BeanFactoryPostProcessor接口的Bean
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
//存放实现了PriorityOrdered接口的回调,会优先执行
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//存放实现了Ordered接口的回调,会次之执行
List<String> orderedPostProcessorNames = new ArrayList<>();
//存放没有实现上面两个接口的回调,最后执行
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
//跳过 - 在前面的阶段已经执行过了
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//筛选出实现了PriorityOrdered的回调
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//筛选出实现了Ordered的回调
orderedPostProcessorNames.add(ppName);
}
else {
//其它没有实现上述两个接口的回调
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
//优先执行postProcessBeanFactory方法
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
//次之执行postProcessBeanFactory方法
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
//最后执行postProcessBeanFactory方法
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
这个方法有点长,这里我总结一下其中干了什么:
- 首先执行 postProcessBeanDefinitionRegistry 方法
- 执行所有硬编码下的
BeanDefinitionRegistryPostProcessor
- 执行容器中的BeanDefinitionRegistryPostProcessor类型的Bean(有Order排序)
- 执行所有硬编码下的
- 然后执行postProcessBeanFactory 方法:
- 执行上述所有的
BeanDefinitionRegistryPostProcessor
- 执行硬编码下不是
BeanDefinitionRegistryPostProcessor
的那些BeanFactoryPostProcessor
- 执行容器中剩余的
BeanFactoryPostProcessor
类型的Bean (有Order排序)
- 执行上述所有的
2.3、BeanFactoryPostProcessor后处理小结
从以上可以知道,我们可以在刚加载完Bean的配置后,拿到registry或是beanFactory,可以对配置中的元数据进行更改,就像开头例子中所描述的,将bean中一个属性占位符替换掉,这个过程是使用了回调方法,
- 但它们都只是容器级别的,父容器不会进行后处理。
我们可以使用上述两种Processor,在Bean初始化之前对Bean的配置信息进行修改,注意是初始化之前,也就代表Bean都没有实例化的时候,这样一来你修改的Bean的配置信息就可以在初始化Bean阶段将Bean初始化成你希望看到的。 - 其中有两个优先级接口,你需要实现此接口,就能获得优先处理的权限,从源码可以看到详细过程:
PriorityOrdered
:最优先,复写getOrder方法设置当前优先级。Ordered
:优先级次之,在PriorityOrdered之后执行,复写getOrder方法设置当前优先级。- 没有实现上述接口最后执行,注意,优先级接口是最优先比较的,然后才会比较getOrder设置的优先级。
3、BeanPostProcessor
此回调与上述回调不同的地方在于,上述关注的时序是在加载完Bean配置信息之后,也就是注重修改Bean配置元信息,BeanPostProcessor回调注重于在Bean初始化完成之后进行的回调,其中AOP则是需要等到Bean初始化完成之后才进行动态代理,不然实例化或是依赖注入都没有完成,就进行动态代理的话, 不符合逻辑不说,还阻止了Bean的初始化过程。
3.1、注册BeanPostProcessor
让我们的时序回到refresh初始化容器中去,此时我们加载完Bean的配置之后,又执行完BeanFactory后处理了,现在将会执行registerBeanPostProcessors(beanFactory); 方法进行BeanPostProcessor
的注册:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
依然是委托另一个类取做的注册:
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//从beanFactory中取出所有BeanPostProcessor类型的beanName
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
//BeanPostProcessor也具有与上面一样的优先级的处理
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//遍历所有找到了的Bean
for (String ppName : postProcessorNames) {
//判断是否为最优先级接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//如果是,则初始化并取出该Bean
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//放入最优先List中
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//判断是否为次之优先接口
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//将名称加入到List中
orderedPostProcessorNames.add(ppName);
}
else {
//剩下的就是最后执行,加入List
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
//先将这些实现最优先接口的类进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//注册这些BeanPostProcessor到beanFactory中
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
//由于上面只是将名称加入,并没有getBean,所以这里先遍历名称
for (String ppName : orderedPostProcessorNames) {
//一一getBean初始化并取出Bean
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//加入次之优先的List
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//排序
sortPostProcessors(orderedPostProcessors, beanFactory);
//注册
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
//同上
for (String ppName : nonOrderedPostProcessorNames) {
//同上
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//没有优先级,最后执行
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//不需要进行排序,直接注册
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
//这里不会重复注册相同的BeanPostProcessor,因为在注册过程会进行去重操作
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
注册过程:
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
//遍历List进行注册
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
/** BeanPostProcessors to apply in createBean */
//存放所有的BeanPostProcessor
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
//先进行去重操作,确保不会重复
this.beanPostProcessors.remove(beanPostProcessor);
//注册,其实就是将此Bean放入一个List中
this.beanPostProcessors.add(beanPostProcessor);
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
}
看完了注册过程,接下来就是调用过程了,这些回调Bean在什么时候会进行回调呢?
3.2、执行BeanPostProcessor
先来看看BeanPostProcessor
接口描述了什么
public interface BeanPostProcessor {
//为在Bean的初始化前提供回调入口
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//为在Bean的初始化之后提供回调入口
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
那么调用时机具体是在哪里呢?进入doCreateBean方法,实例化且依赖注入完成:
//这里是依赖注入
populateBean(beanName, mbd, instanceWrapper);
//initializeBean为执行回调的方法,注意此时已经初始化且依赖注入完了
exposedObject = initializeBean(beanName, exposedObject, mbd);
//初始容器创建的Bean实例对象,为其添加BeanPostProcessor后置处理器
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//JDK的安全机制验证权限
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//为Bean实例对象包装相关属性,如名称,类加载器,所属容器等信息
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
//对BeanPostProcessor后置处理器的postProcessBeforeInitialization
//回调方法的调用,为Bean实例初始化前做一些处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置
//文件中通过init-method属性指定的
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
//对BeanPostProcessor后置处理器的postProcessAfterInitialization
//回调方法的调用,为Bean实例初始化之后做一些处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
我们来一一分析这些扩展点:
3.2.1、部分Aware接口的回调
首先是invokeAwareMethods方法:
private void invokeAwareMethods(final String beanName, final Object bean) {
//Bean如果继承了Aware,将会执行Bean的一些Aware方法
if (bean instanceof Aware) {
//如果是实现BeanNameAware的话
if (bean instanceof BeanNameAware) {
//将此Bean的BeanName放入此方法参数并执行
((BeanNameAware) bean).setBeanName(beanName);
}
//如果是实现BeanClassLoaderAware的话
if (bean instanceof BeanClassLoaderAware的话) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
//将ClassLoader放入此方法参数并执行
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
//如果是实现BeanFactoryAware的话
if (bean instanceof BeanFactoryAware) {
//放入beanFactory实例
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
这里只是部分三个Aware,后面还有一些Aware接口,以供有需要的Bean注入你需要的资源,例如,你只需要实现BeanFactoryAware这个接口,实现setBeanFactory方法,即可拿到beanFactory实例,Aware接口方便的提供了你所需要的资源。
3.2.2、Bean的前处理
前处理由applyBeanPostProcessorsBeforeInitialization方法执行:
@Override
//调用BeanPostProcessor后置处理器实例对象初始化之前的处理方法
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
//调用Bean实例所有的后置处理中的初始化前处理方法,为Bean实例对象在
//初始化之前做一些自定义的处理操作
Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
这里**getBeanPostProcessors()**方法会将我们前面所说的注册的那些BeanPostProcessor
全部遍历执行,因为已经优先级排序add了,所以此时List都是有序执行的。
3.2.3、Bean的自定义初始化
由invokeInitMethods开始Bean的初始化处理,注意此时不是指实例化与依赖注入,这两个过程已经执行过:
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
//判断Bean是否实现了InitializingBean接口,实现了才会进行自定义初始化
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
//执行自定义初始化方法
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//执行自定义初始化方法
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
//寻找配置Bean时配置的init方法
String initMethodName = mbd.getInitMethodName();
//这里会先忽略掉afterPropertiesSet这个方法,因为已经执行过了
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//这里会获取Method对象,执行你配置的init方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
由上面的代码可以知道,在自定义初始化中,你有两种方法可以进行自定义初始化:
- 实现
InitializingBean
接口
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
在afterPropertiesSet方法中实现你所自定义的逻辑
2. 在配置Bean时配置一个init方法
3.2.4、Bean的后处理
在applyBeanPostProcessorsAfterInitialization方法完成:
@Override
//调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
//调用Bean实例所有的后置处理中的初始化后处理方法,为Bean实例对象在
//初始化之后做一些自定义的处理操作
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
与后处理一样,遍历所有已经注册过的BeanPostProcessor
进行轮流调用postProcessAfterInitialization方法。
3.3、其他的Aware接口
在refresh方法中,加载Bean配置之后,执行BeanFactory后处理之前,其实还注册了一些BeanPostProcessor
,是在refresh的prepareBeanFactory方法中注册的:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//略...
// Configure the bean factory with context callbacks.
//这里会添加一个回调Aware的Processor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//忽略以下Aware接口,不进行依赖注入
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
//注册以下类型,在依赖注入时如果遇到例如BeanFactory类型的依赖,直接注入beanFactory的值
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//略...
}
这里略过一些暂时不讨论的方法,可以知道,这里会固定注册一个名为ApplicationContextAwareProcessor
的Processor,来看看它的前后处理方法都做了什么吧:
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
在后处理中没有做任何逻辑,继续看看前处理:
@Override
@Nullable
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
//执行Aware接口的方法
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
//执行Aware接口的方法
invokeAwareInterfaces(bean);
}
return bean;
}
这里大部分都在判断一些其他的东西,我们重点只看invokeAwareInterfaces:
private void invokeAwareInterfaces(Object bean) {
//判断Bean是Aware才往下执行
if (bean instanceof Aware) {
//如果实现了EnvironmentAware
if (bean instanceof EnvironmentAware) {
//将applicationContext的enviroment变量放入
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
//如果实现了ResourceLoaderAware
if (bean instanceof ResourceLoaderAware) {
//将资源加载器放入
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
//如果实现了ApplicationContextAware
if (bean instanceof ApplicationContextAware) {
//将上下文对象放入
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
这里我就不一一注释说明了,也就是说,容器在Bean初始化完成之后,会判断此Bean是否是Aware,除了上述我们说的那三个Aware,这里还有很多个Aware供用户实现,可以拿到更多各种各样的资源。
3.4、其他的BeanPostProcessor
这里还有一种BeanPostProcessor的调用时序,即为BeanPostProcessor的子类InstantiationAwareBeanPostProcessor
:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
//在Bean实例化之前的回调入口
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
//Bean实例化之前,上面的回调入口之后的入口
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
//在Bean实例化之后,依赖注入时对注入属性进行更改的回调入口
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
这个接口提供了更加多的回调时机的入口,并且额外提供了在依赖注入时的回调时机入口。我们需要关注的点就在,这些入口究竟在什么地方执行?
首先看看前处理的时机。回到实际创建Bean实例的方法中:
//创建Bean实例对象
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//略..
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
//判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
//略..
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//执行上述的回调入口
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
//略..
try {
//创建Bean的入口
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
//略..
}
其中resolveBeforeInstantiation方法执行了两个回调,从这里我们可以知道,时机就在实例化Bean之前,此时Bean甚至连实例化都还没做:
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//刚开始beforeInstantiationResolved为null,所以第一次是会进入该if语句块的
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
//这里会保证该Bean是已经被处理过的才会进入这里(除了第一次)
//不知读者是否记得,在注册BeanPostProcessor的时候,
//会判断该BeanPostProcessor是否是InstantiationAwareBeanPostProcessor
//如果是的话,hasInstantiationAwareBeanPostProcessors会为true,进入以下语句块
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//回调入口,进行回调前处理
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//如果bean不为空,代表已经自定义实例化了,所以这里不是执行InstantiationAwareBeanPostProcessor的回调后处理
//而是执行普通BeanPostProcessor的回调后处理,后面读者可以注意一下
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
//bean不为null,证明被处理过了,下一次将还会进入这个语句块
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//只执行那些InstantiationAwareBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
//前处理回调入口
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
@Override
//调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
//调用Bean实例所有的后置处理中的初始化后处理方法,为Bean实例对象在
//初始化之后做一些自定义的处理操作
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
注意,InstantiationAwareBeanPostProcessor
与上述的BeanPostProcessor
使用场景不一样,InstantiationAwareBeanPostProcessor
的前处理更多是希望将你想要的Bean根据你自己的方式进行自定义实例化,所以你可以看到,在creatBean的主逻辑中,只要该前处理返回的Bean不为null,即代表此Bean已经自定义初始化完成,会接着去执行普通BeanPostProcessor
的后处理,当这里返回的Bean不为null,在createBean方法中,将不会进行后面的操作(例实例化、依赖注入、回调初始化之类之类的操作),直接返回InstantiationAwareBeanPostProcessor
前处理之后返回的bean。
其次看看后处理和依赖注入回调的时机,我们来到依赖注入的方法populateBean :
//将Bean属性设置到生成的实例对象上
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//略..
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
//上面说过,在注册时会判断,存在即hasInstantiationAwareBeanPostProcessors为true
//所以此时可以根据注册时的判断来判断是否存在InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//只执行InstantiationAwareBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//执行后处理
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
//如果后处理中有返回false的,这里将不进行依赖注入直接返回了
if (!continueWithPropertyPopulation) {
return;
}
//略..
//对非autowiring的属性进行依赖注入处理
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//只处理InstantiationAwareBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//这里执行依赖注入的回调
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
//这里返回值为null,将不进行依赖注入,直接返回
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
//对属性进行注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
到这里我们可以知道,InstantiationAwareBeanPostProcessor
的后处理是为了判断是否依赖注入的,如果返回false,将不进行依赖注入的功能,而依赖注入的回调方法,是为了对注入的属性进行某种自定义操作的,如果不返回null,将会根据自定义处理了的PropertyValues
属性值进行依赖注入。
3.5、小结
-
实现Aware接口: 实现对应方法,方法中可以拿到你想要的资源
-
实现InitializingBean接口: 在接口方法中实现你所想要初始化的逻辑,此时序是在Bean实例化且依赖注入完,Bean进行前处理之后,后处理之前会调用的。
-
实现BeanPostProcessor接口:在接口两个入口中实现你所想要操作Bean的逻辑,前处理的时序是在Bean实例化且依赖注入完成之后,后处理的时序是在前处理完成且初始化方法完成之后。
-
实现InstantiationAwareBeanPostProcessor接口:
- 实现前处理方法: 你 可以自定义Bean的初始化过程,将不会执行之后Spring的创建Bean方法doCreateBean,直接返回你所自定义的Bean实例。
- 实现后处理方法: 你可以自定义当前Bean是否进行依赖注入,返回false就不会进行依赖注入了。
- 实现依赖注入回调方法: 你可以操作注入的属性值,使用自定义操作后的属性值进行依赖注入,同时返回null将不会进行依赖注入。
4、事件驱动编程(监听器)
4.1、初始化监听器的管理器
回忆一下refresh方法,其中有一个过程是初始化监听器容器initApplicationEventMulticaster:
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判断beanFactory中是否存在名为applicationEventMulticaster的Bean
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
//如果有,初始化该Bean并取出
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
//如果到了这里,说明没有自定义applicationEventMulticaster
//Spring默认会创建一个SimpleApplicationEventMulticaster
//放入IOC容器,将其当作是监听器容器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
//注册此实例到IOC容器中
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
如果用户没有自定义监听器容器,将配置一个默认的监听器容器。
4.2、注册监听器
回到refresh方法,接下来会注册各个监听器registerListeners:
protected void registerListeners() {
// Register statically specified listeners first.
//首先注册硬编码的监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
//获取所有IOC容器中ApplicationListener类型的BeanName
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
//遍历BeanName,依次注册
for (String listenerBeanName : listenerBeanNames) {
//这里会使用我们上面初始化好的监听器容器去注册监听器
//不要担心重复,监听器是用Set集合存放,自带去重功能
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
注册监听器必须是要有监听器容器,所以上面会先初始化一个监听器容器,如果用户没有设置,那么Spring将默认创建一个出来。
4.3、发布事件通知
注册监听器的过程,我们可以知道,监听器统一存放在名为applicationEventMulticaster的Bean中,统一管理。此Bean默认实现是SimpleApplicationEventMulticaster
:
//通知监听器的方法
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
//获取所有的监听器,遍历它们
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
//通知监听器
executor.execute(() -> invokeListener(listener, event));
}
else {
//通知监听器
invokeListener(listener, event);
}
}
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
//真正通知监听器的方法
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
//真正通知监听器的方法
doInvokeListener(listener, event);
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
//调用监听器的onApplicationEvent方法,传入一个事件源
listener.onApplicationEvent(event);
}
//catch过程,略...
}
我们可以知道,监听器容器统一管理监听器,并对外提供通知监听器的方法,可以看出onApplicationEvent
方法即为监听器的回调方法:
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
是一个功能接口,面向函数式编程,其中方法定义为传入一个源(这里的源必须是ApplicationEvent
的)。返回空值。
4.4、ApplicationContext发布事件发布通知
那么在Spring中是什么时候会通知监听器的呢?在AbstractApplicationContext
中有这样一个方法:
@Override
public void publishEvent(ApplicationEvent event) {
//传入事件源
publishEvent(event, null);
}
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Publishing event in " + getDisplayName() + ": " + event);
}
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
//对事件源类型进行处理
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
}
}
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
//执行通知的方法,同时所有监听器
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
//如果有父容器,也通知父容器的监听器
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
//父容器也发布事件进行通知
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
//父容器也发布事件进行通知
this.parent.publishEvent(event);
}
}
}
也就是说,我们如果可以拿到ApplicationContext
对象,通过调用该对象的publishEvent方法,即可发布事件并且通知所有监听器。
在开头我们也有提到,在IOC容器初始化完成的末尾,会执行一个方法finishRefresh,此方法内部会发布事件进行通知,告诉监听器此时IOC容器初始化完成:
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
//发布事件源,封装当前对象,发布通知
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
此时正是执行了我们上面分析的发布事件源发布通知的方法publishEvent
4.5、小结
- 自定义监听器容器: 需将此BeanName设置为applicationEventMulticaster 的Bean,或者不自定义也是可以的,Spring会提供一个默认的监听器容器。
- 配置监听器:让Bean实现
ApplicationListener
接口,这样这个Bean就是一个监听器,Spring会注册它。然后在方法中可以定义对应事件驱动的方法。 - 发布事件通知:可以通过
Aware
接口,或是@Autowired依赖注入一个ApplicationContext,拿到上下文对象之后,执行publishEvent方法即可发布通知给监听器。
5、Lifecycle
参考《Spring源码深度解析》一书:在Spring中还提供了Lifecycle接口,Lifecycle中包含start/stop方法,实现此接口后Spring会保证在启动的时候调用其start方法开始生命周期,并在Spring关闭的时候调用stop方法来结束生命周期,通常用来配置后台程序,在启动后一直允许(如对MQ进行轮询等)。而ApplicationContext的初始化最后正式保证了这一功能的实现。
这里提到ApplicationContext
的初始化最后,正是我们上面提到的finishRefresh方法:
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
//先初始化LifecycleProcessor
//此类类似上述监听器容器,用来管理所有Lifecycle的Bean
//负责调用Lifecycle的Bean的start/stop方法
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
//委派上述初始化的LifecycleProcessor去调用start方法
getLifecycleProcessor().onRefresh();
// Publish the final event.
//发布事件源,封装当前对象,发布通知
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
5.1、初始化Lifecycle的管理器
Lifecycle
类似上面说到的监听器容器(管理器),用于管理实现Lifecycle
接口的Bean,
initLifecycleProcessor():
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判断beanFactory中是否有名为lifecycleProcessor的Bean
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
//如果有,将其初始化并取出,作为Lifecycle的管理器
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isDebugEnabled()) {
logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else {
//如果用户没有自定义lifecycleProcessor,Spring将默认创建一个
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
//作为Lifecycle的管理器
this.lifecycleProcessor = defaultProcessor;
//将此Lifecycle的管理器注册到IOC容器中作为一个Bean
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate LifecycleProcessor with name '" +
LIFECYCLE_PROCESSOR_BEAN_NAME +
"': using default [" + this.lifecycleProcessor + "]");
}
}
}
类似的,Lifecycle
的管理器也可以自定义,若用户没有自定义,则创建一个默认的。
5.2、Lifecycle开始生命周期
由于此时IOC容器已经初始化完成,所以将会开启所有Lifecycle
的start方法,方式就是委派管理器去执行getLifecycleProcessor().onRefresh():
@Override
public void onRefresh() {
startBeans(true);
this.running = true;
}
private void startBeans(boolean autoStartupOnly) {
//拿到所有容器中实现Lifecycle接口的Bean
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new HashMap<>();
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
int phase = getPhase(bean);
LifecycleGroup group = phases.get(phase);
if (group == null) {
group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
phases.put(phase, group);
}
group.add(beanName, bean);
}
});
if (!phases.isEmpty()) {
List<Integer> keys = new ArrayList<>(phases.keySet());
Collections.sort(keys);
for (Integer key : keys) {
//执行Lifecycle的start方法
phases.get(key).start();
}
}
}
至于stop方法,我没有去找具体在哪里执行,不过我猜想应该是在容器关闭时就会执行stop方法。
6、总结
以上,我们说了很多很多关于Spring的扩展点,这里再进行总结一下。
- 如果你希望修改Bean的配置信息, 并且在Bean初始化的时候可以被使用到:可以实现
BeanFactoryPostProcessor
接口,在相应回调方法中实现相应的逻辑。具体应用:配置Bean时占位符的替换,亦或是某些Bean的属性转换(电话号码中间几位的屏蔽),总而言之如果希望修改Bean配置信息,按照你希望的配置来进行初始化,就实现此接口。 - 如果你希望在Bean初始化完成之后对Bean有什么操作:可以实现
BeanPostProcessor
接口。具体应用:AOP,AOP的原理其实是动态代理,实现AOP的核心类就实现了BeanPostProcessor
接口,并且保证在Bean初始化(实例化与依赖注入)之后进行后处理,判断Bean是否应该被AOP,如果需要,则动态代理此Bean,返回代理后的proxy对象,IOC容器将使用proxy对象作为此Bean,完成AOP的操作。 - 如果你希望某个Bean按照你的方式进行初始化:而不是IOC那些实例化、依赖注入、各种回调方法,那么你可以实现
InstantiationAwareBeanPostProcessor
,实现前处理方法来自定义Bean的初始化过程,返回实例即为此Bean,如果返回null的话IOC容器将继续初始化该Bean,所以可以判断某个Bean是自定义的初始化,剩下的Bean依然可以正常初始化。 - 如果你希望修改某个Bean的依赖注入属性,亦或是控制某个Bean不要进行依赖注入:你可以实现
InstantiationAwareBeanPostProcessor
这个接口的依赖注入回调方法或是后处理方法。前者可以返回一个你修改后的属性封装对象,在接下来的处理中会针对你修改后的属性封装对象进行依赖注入,如果返回null将不会进行依赖注入。而后者只控制是否进行依赖注入,两者的区别与时序希望读者区分清楚,它们的共同点在都可以控制是否进行依赖注入,但侧重点不同。 - 如果你希望获取容器的某个资源:例如ClassLoader、BeanFactory、ApplicationContext、ResourceLoader等等一系列资源,你可以实现相对应的Aware接口,并且将类交给IOC容器管理,此类作为Bean将在你实现的Aware接口的对应方法中注入你所想要的属性。亦或是使用依赖注入的方式,也可以得到你想要的资源,原理在上面的3.3节其他的Aware接口中有提到,注册了对应的依赖:
@Autowired
private ApplicationContext applicationContext
- 如果你希望在Bean初始化完,执行一个类似初始化的方法:你可以实现
InitializingBean
接口,在对应方法中实现你想初始化的逻辑,时机是在Bean实例化、依赖注入、BeanPostProcessor
的前处理之后,后处理之前将会执行的。 - 如果你希望注册监听器:实现
ApplicationListener
接口,并将类交给IOC容器管理,就可以自动注册监听器了,然后在对应方法中写具体通知方法之后需要做的事件逻辑。注册完监听器,就少不了发布事件,你可以在任意地方获取到上下文对象(方式有两种,上面都有提到),然后调用上下文对象的publishEvent方法即可发布事件,你所配置的监听器都会收到消息并执行你自定义的逻辑。 - 如果你希望伴随IOC容器有一个生命周期的动作:你可以让类实现
Lifecycle
接口,实现对应start/stop方法,其将会在容器初始化完成后执行start,在start中开始此Bean的生命周期的逻辑,达到一个生命周期的效果。
讲到这里,IOC容器的介绍也就告一段落了,我希望读者看到这里,能意识到IOC容器并不是解耦那么简单,因为有了IOC容器,才有AOP,才有各种各样灵活的处理,如果没有IOC容器去管理那些对象,我们需要做的事情可多太多太多了,IOC容器管理对象,极大简化了我们的开发过程。