spring扩展原理
Posted programmlover
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring扩展原理相关的知识,希望对你有一定的参考价值。
一 BeanFactoryPostProcessor的作用及原理:
1、BeanFactoryPostProcessor的作用:在BeanFactory标准初始化之后调用,所有的bean已保存加载到beanFactory,但是bean的实例还未创建
2、示例:
@Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{ //这个方法会在bean实例创建之前调用 @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("postProcessBeanFactory..."); String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); int beanDefinitionCount = beanFactory.getBeanDefinitionCount(); System.out.println("当前beanFactory中有"+ beanDefinitionCount +"个bean,这些bean的名字是"+Arrays.toString(beanDefinitionNames)); } }
3、原理:查看构造器 public AnnotationConfigApplicationContext(Class<?>... annotatedClasses),
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh(); }
我们会发现构造器调用了refresh()方法,进入refresh()方法
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //第一步,预创建bean对象 // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { //第二步,调用invokeBeanFactoryPostProcessors(beanFactory)方法 // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); ...; //初始化bean对象实例 // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); ...; }
我们会发现 invokeBeanFactoryPostProcessors 在创建bean对象之后且在初始化bean实例之前调用,这就是他的原理
进入invokeBeanFactoryPostProcessors ,再进入 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
这个方法会直接在BeanFactory中找到所有类型为BeanFactoryPostProcessor的方法并且执行他们。
二 BeanFactoryPostProcessor 子接口 BeanDefinitionRegistryPostProcessor接口的作用:
1、BeanDefinitionRegistryPostProcessor 新增了一个方法: void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
这个方法的作用: 在所有bean信息将要被加载,bean实例还未创建时调用,所以 postProcessBeanDefinitionRegistry方法将会优先于 postProcessBeanFactory方法被调用
2、示例:
@Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { int beanDefinitionCount = beanFactory.getBeanDefinitionCount(); System.out.println("当前beanFactory中有"+ beanDefinitionCount +"个bean"); } @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { System.out.println("当前beanFactory中有"+ registry.getBeanDefinitionCount() +"个bean"); AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition(); registry.registerBeanDefinition("newAddBean", beanDefinition); } }
三 ApplicationListener 的用法:
1、 ApplicationListener 作用:监听容器中发布的事件。事件驱动模型开发。
ApplicationListener 接口定义:public interface ApplicationListener<E extends ApplicationEvent> extends EventListener
1) 监听范围:监听 ApplicationEvent 及其下面的子类
ContextClosedEvent //Context关闭事件
ContextRefreshedEvent //Context刷新事件
ContextStartedEvent //Context开始事件
ContextStoppedEvent //Context停止事件
2、基于事件驱动模型开发步骤:
1) 写一个监听器来监听某个事件,这个事件必须是 ApplicationEvent 及其下面的子类
2) 把监听器加入容器中
3)只要容器中有相关类型事件发布,我们就能监听到这个事件
3、示例
@Component public class MyApplicationListener implements ApplicationListener<ApplicationEvent>{ //当容器中发布此事件,方法会得到触发 @Override public void onApplicationEvent(ApplicationEvent event) { System.out.println("收到事件:"+event); } }
四 ApplicationListener 原理
1、ContextRefreshedEvent事件:
1)、容器创建对象:refresh();
2)、refresh() 调用 finishRefresh();容器刷新完成会发布ContextRefreshedEvent事件
3)、finishRefresh() 调用 publishEvent(new ContextRefreshedEvent(this));
【事件发布流程】: publishEvent(new ContextRefreshedEvent(this));
1)、publishEvent 方法获取事件的多播器(派发器):getApplicationEventMulticaster()
2)、multicastEvent派发事件:
3)、multicastEvent方法获取到所有的ApplicationListener;
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
1)、if (有Executor) {
可以支持使用Executor进行异步派发;
Executor executor = getTaskExecutor();
} else {
同步的方式直接执行listener方法;invokeListener(listener, event);
拿到listener回调onApplicationEvent方法;
}
【事件多播器(派发器)】
1)、容器创建对象:refresh();
2)、refresh() 方法调用 initApplicationEventMulticaster();初始化ApplicationEventMulticaster;
1)、先去容器中找有没有id=“applicationEventMulticaster”的组件;
2)、如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster
【容器中有哪些监听器】
1)、容器创建对象:refresh();
2)、refresh() 调用 registerListeners() :从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中;
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
3)、 //将listener注册到ApplicationEventMulticaster中: getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)
五 @Listener注解的应用:
1、@Listener用法:@EventListener(classes= { ${class event ApplicationEvent} ,...}) ,将这个注解标在方法上spring在启动的时候就会将这个方法创建成一个监听器,
注意:方法中必须要有一个ApplicationEvent及其子类的参数来接收事件
2、示例:
@Service public class ListenerService { @EventListener(classes= {ApplicationEvent.class}) public void Listener(ApplicationEvent event) { System.out.println("@EventListener收到事件:"+event); } }
六 @Listener的原理:
1、@Listener 使用 EventListenerMethodProcessor来处理
2、EventListenerMethodProcessor 实现了 SmartInitializingSingleton 接口,主要就是这个接口在起作用
3、SmartInitializingSingleton 原理:afterSingletonsInstantiated() 方法
1)、ioc容器创建对象并refresh();
2)、finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean;
1)、先创建所有的单实例bean;getBean();
2)、获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;
如果是就调用afterSingletonsInstantiated();
以上是关于spring扩展原理的主要内容,如果未能解决你的问题,请参考以下文章