扩展原理BeanFactoryPostProcessor
package jane.ext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/*
* 扩展原理:
* 类似的:BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作
* BeanFactoryPostProcessor:beanFactory的后置处理器
* 原码解析:
* * Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
在BeanFactory标准初始化之后可以调用它修改BeanFactory,
标准初始化就是所有的bean定义信息已经保存加载到beanfactory,但是bean的实例还没创建
步骤:
1)IOC容器创建对象
1)invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessors
任何找到所有的BeanFactoryPostProcessor并且执行他们的方法
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
1)直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
这些方法都是在创建其他组件前面执行的
*/
import jane.bean.Car;
@ComponentScan("jane.ext")
@Configuration
public class MyConfigOfExt
{
@Bean
public Car car()
{
return new Car();
}
}
package jane.ext;
import java.util.Arrays;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor
{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
System.out.println("MyBeanFactoryPostProcessor.postProcessBeanFactory");
int count = beanFactory.getBeanDefinitionCount();
String[] names = beanFactory.getBeanDefinitionNames();
System.out.println("定义的bean的个数:"+count);
System.out.println(Arrays.toString(names));
}
}
BeanDefinitionRegistryPostProcessor
这是BeanFactoryPostProcessor的一个子接口
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
里面有一个抽象方法void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
这个方法是在所有的bean定义信息将要被加载,bean实例还没创建的时候调用
优先于BeanFactoryPostProcessor执行
利用BeanDefinitionRegistryPostProcessor给容器再额外添加一些组件
对应的实现类
package jane.ext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;
import jane.bean.Car;
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor
{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
System.out.println("MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory的bean数量:"+beanFactory.getBeanDefinitionCount());
}
/*
* BeanDefinitionRegistry是bean定义信息的保存中心,以后的BeanFactory就是按照
* BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例的
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException
{
System.out.println("postProcessBeanDefinitionRegistry的bean数量"+registry.getBeanDefinitionCount());
/*
* 我们还可以使用BeanDefinitionRegistry来注册一些bean
* 注册bean需要beanDefinition(bean的定义信息),有很多方法创建beanDefinition
*/
// RootBeanDefinition beanDefinition = new RootBeanDefinition(Car.class);
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Car.class).getBeanDefinition();
registry.registerBeanDefinition("hello", beanDefinition);
}
}
结果
九月 09, 2020 7:29:16 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 19:29:16 CST 2020]; root of context hierarchy
postProcessBeanDefinitionRegistry的bean数量10
MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory的bean数量:11
MyBeanFactoryPostProcessor.postProcessBeanFactory
定义的bean的个数:11
[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, myConfigOfExt, myBeanDefinitionRegistryPostProcessor, myBeanFactoryPostProcessor, car, hello]
九月 09, 2020 7:29:16 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
car constructor...
car constructor...
九月 09, 2020 7:29:16 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 19:29:16 CST 2020];
原码查看
首先还是创建IOC容器,调用refresh();刷新容器
调用invokeBeanFactoryPostProcessors(beanFactory);
调用invokeBeanFactoryPostProcessors
调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
可以看到,里面的currentRegistryProcessors就保存了MyBeanDefinitionRegistryPostProcessor
那么currentRegistryProcessors是如何得到的呢?

也可以发现,他们也像BeanFactoryPostProcessor一样,通过类型来获取,还是按照优先级来获取的,然后执行invokeBeanDefinitionRegistryPostProcessors()方法


然后再触发BeanFactoryPostProcessor接口的postProcessBeanFactory()方法

为什么BeanDefinitionRegistryPostProcessor的方法比BeanFactoryPostProcessor接口的方法还要早执行?
可以看到在这个方法后面才执行BeanFactoryPostProcessor接口的方法

ApplicationListener
package jane.ext;
import java.util.EventListener;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/*
* ApplicationListener:监听容器中发布的事件,实现事件驱动模型开发
* public interface ApplicationListener<E extends ApplicationEvent> extends EventListener
* 监听ApplicationEvent及其下面的子事件
*
* 步骤:
* 1.先写一个监听器来监听某个事件(ApplicationEvent及其子类)
* 2.把监听器加入到容器中
* 3.只要是容器中有关事件的发布,我们就能监听到这个事件
*
* ContextRefreshedEvent:容器刷新完成(所有的bean都完成创建)就会发布这个事件
* ContextClosedEvent:关闭容器就会发布这个事件
* 4.自己发布一个事件
*/
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent>
{
@Override
public void onApplicationEvent(ApplicationEvent event)
{
System.out.println("收到事件"+event);
}
}
测试
package jane;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import jane.ext.MyConfigOfExt;
public class IOCTestExt
{
@org.junit.Test
public void TestExt()
{
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfigOfExt.class);
applicationContext.publishEvent(new ApplicationEvent(new String("自己发布事件")){});
applicationContext.close();
}
}
结果
九月 09, 2020 8:17:00 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 20:17:00 CST 2020]; root of context hierarchy
postProcessBeanDefinitionRegistry的bean数量11
MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory的bean数量:12
MyBeanFactoryPostProcessor.postProcessBeanFactory
定义的bean的个数:12
[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, myConfigOfExt, myApplicationListener, myBeanDefinitionRegistryPostProcessor, myBeanFactoryPostProcessor, car, hello]
九月 09, 2020 8:17:00 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
car constructor...
car constructor...
收到事件org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 20:17:00 CST 2020]; root of context hierarchy]
收到事件jane.IOCTestExt$1[source=自己发布事件]
九月 09, 2020 8:17:01 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 20:17:00 CST 2020]; root of context hierarchy
收到事件org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@21588809: startup date [Wed Sep 09 20:17:00 CST 2020]; root of context hierarchy]
原理
原码调试看看上面三个事件是如何创建的
首先还是老样子,容器创建对象,refresh();容器进行刷新
调用了finishRefresh();容器刷新完成,进入到里面看看

里面正是调用了publishEvent(new ContextRefreshedEvent(this));
发布一个容器刷新完成的事件
进入到publishEvent(),查看事件到底是如何发布的?
事件发布流程
@Override
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}
进入publishEvent(event, null);
发现里面先获取事件多播器(派发器)getApplicationEventMulticaster()
然后执行multicastEvent(applicationEvent, eventType)进行派发事件

那怎么进行派发呢?进入到multicastEvent()里面去
发现首先是获取到所有的ApplicationListener
如果有Executor就可以支持使用Executor进行异步派发(开多一个线程),效率更高
如果没有,就同步的方式直接执行listener方法invokeListener(listener, event);
然后这些带有invoke的方法执行套路都差不多
调用doInvokeListener(listener, event);
然后拿到listener回调onApplicationEvent方法
listener.onApplicationEvent(event);

看完上面,会有这个问题,那个事件多播器(派发器)这个玩意干嘛的?
applicationEventMulticaster
还是常规套路,容器创建对象,refresh();
在refresh的时候initApplicationEventMulticaster()
初始化applicationEventMulticaster

进入initApplicationEventMulticaster()
先去容器中找有没有id="applicationEventMulticaster"的组件
如果没有就自己创建一个SimpleApplicationEventMulticaster
并且加入到容器中,我们就可以在其他组件要派发事件,自动注入applicationEventMulticaster

还有它怎么知道容器中有那些监听器的?
容器创建对象,refresh();
里面有个registerListeners(),注册监听器

从容器中拿到所有的监听器,把他们注册到多播器,是按照类型来找的监听器的

@EventListener
package jane.ext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class TestListener
{
@EventListener({ApplicationEvent.class})
public void listener(ApplicationEvent event)
{
System.out.println("TestListener收到监听事件"+event);
}
}
原理
使用EventListenerMethodProcessor处理器来解析方法上的@EventListener
现在我们就进入EventListenerMethodProcessor
public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware {
EventListenerMethodProcessor实现了SmartInitializingSingleton,这个SmartInitializingSingleton就是我们要查看的原理所在
进入SmartInitializingSingleton查看
根据上面的注释,说当所有的单实例已经创建完成之后,才会执行这个方法
触发时机类似于ContextRefreshedEvent

现在debug查看调用原理
首先IOC容器创建对象,refresh()
然后finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean,
beanFactory.preInstantiateSingletons();
1)首先创建所有的单实例bean,getBean();
2)然后获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的
如果是就调用afterSingletonsInstantiated();