浅尝Spring注解开发_简单理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener

浅尝Spring注解开发_简单理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener

浅尝Spring注解开发,基于Spring 4.3.12
分析BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener

浅尝Spring注解开发_自定义注册组件、属性赋值、自动装配
浅尝Spring注解开发_Bean生命周期及执行过程
浅尝Spring注解开发_AOP原理及完整过程分析(源码)
浅尝Spring注解开发_声明式事务及原理
浅尝Spring注解开发_简单理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener
Spring注解开发_Spring容器创建概述
浅尝Spring注解开发_Servlet3.0与SpringMVC

BeanFactoryPostProcessor

  • BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的
  • BeanFactoryPostProcessor:beanFactory的后置处理器
    • BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容
    • 所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建

原理

  1. ioc容器创建对象
  2. refresh()->invokeBeanFactoryPostProcessors(beanFactory)
    • 如何找到所有的BeanFactoryPostProcessor并执行他们的方法?
      1. 直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,
      2. 按照Ordered接口排序
      3. 依次执行它们的方法。在初始化创建其他组件前面执行
@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("当前BeanFactory中有"+count+" 个Bean");
		System.out.println(Arrays.asList(names));
	}
}

输出

MyBeanFactoryPostProcessor...postProcessBeanFactory...
当前BeanFactory中有9 个Bean
//[输出所有BeanDefinitionNames...]
//创建注入容器中的一个Bean
blue...constructor

BeanDefinitionRegistryPostProcessor

  • BeanDefinitionRegistryPostProcessor
    • 继承自BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
    • postProcessBeanDefinitionRegistry()在所有bean定义信息将要被加载,bean实例还未创建
  • 优先于BeanFactoryPostProcessor执行
  • 利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件

原理

  1. ioc创建对象
  2. refresh()->invokeBeanFactoryPostProcessors(beanFactory)
  3. 从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件
    1. 同样实现了Ordered接口排序,依次触发所有的postProcessBeanDefinitionRegistry()方法
    2. 再来触发BeanFactoryPostProcessor方法postProcessBeanFactory()
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的数量:"+beanFactory.getBeanDefinitionCount());
	}

	//BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例;
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessBeanDefinitionRegistry...bean的数量:"+registry.getBeanDefinitionCount());
        
        //再注册一个Bean,两种不同方法
		//RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
		registry.registerBeanDefinition("hello", beanDefinition);
	}
}

输出

//下面两个都是MyBeanDefinitionRegistryPostProcessor方法,由于在方法内又手动注册了一个,所以是11个
postProcessBeanDefinitionRegistry...bean的数量:10
MyBeanDefinitionRegistryPostProcessor...bean的数:11
//下面一个是BeanFactoryPostProcessor方法
MyBeanFactoryPostProcessor...postProcessBeanFactory...
当前BeanFactory中有11 个Bean
//输出所有BeanDefinitionNames...
[org.springframework...]
//两个Bean
blue...constructor
blue...constructor

ApplicationListener

  • ApplicationListener:监听容器中发布的事件。事件驱动模型开发

  • public interface ApplicationListener<E extends ApplicationEvent>:监听 ApplicationEvent 及其下面的子事件

步骤

  1. 写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类),或者使用@EventListener注解标注在监听方法上
  2. 把监听器加入到容器
  3. 只要容器中有相关事件的发布,我们就能监听到这个事件
    • ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件
    • ContextClosedEvent:关闭容器会发布这个事件
  4. 发布一个事件
    • applicationContext.publishEvent()

自定义监听器

@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {

	//当容器中发布此事件以后,方法触发
	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		// TODO Auto-generated method stub
		System.out.println("收到事件:"+event);
	}
}
@Service
public class UserService {
	
	@EventListener(classes={ApplicationEvent.class})
	public void listen(ApplicationEvent event){
		System.out.println("UserService..监听到的事件:"+event);
	}

}

发布事件

public class IOCTest_Ext {
	
	@Test
	public void test01(){
		AnnotationConfigApplicationContext applicationContext  = new AnnotationConfigApplicationContext(ExtConfig.class);
		
		//发布事件;
		applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
		});
		
		applicationContext.close();
	}

}

输出

//注入Bean
blue...constructor
//监听容器刷新事件
UserService..监听到的事件:org.springframework.context.event.ContextRefreshedEvent[]
收到事件:org.springframework.context.event.ContextRefreshedEvent[]
UserService..监听到的事件:com.atguigu.test.IOCTest_Ext$1[source=我发布的事件]
//监听自定义事件
UserService..监听到的事件:org.springframework.context.event.ContextClosedEvent[]
收到事件:com.atguigu.test.IOCTest_Ext$1[source=我发布的事件]
//监听容器关闭事件
UserService..监听到的事件:org.springframework.context.event.ContextClosedEvent
收到事件:org.springframework.context.event.ContextClosedEvent[]

原理

  1. 发布ContextRefreshedEvent事件为例:

    1. 容器创建对象:refresh()

    2. finishRefresh(),容器刷新完成

      事件发布流程:

      1. 获取事件的多播器(派发器)getApplicationEventMulticaster()

      2. multicastEvent派发事件

      3. 获取到所有的ApplicationListener

        for (final ApplicationListener<?> listener : getApplicationListeners(event, type))

        1. 如果有Executor,可以支持使用Executor进行异步派发:Executor executor = getTaskExecutor()
        2. 否则,同步的方式直接执行listener方法:invokeListener(listener, event)
        3. 拿到listener回调onApplicationEvent方法
  2. 发布自定义事件

  3. 容器关闭发布ContextClosedEvent事件

事件多播器(派发器)

  1. 容器创建对象:refresh()
  2. initApplicationEventMulticaster():初始化ApplicationEventMulticaster
    1. 先去容器中找有没有id="applicationEventMulticaster"的组件
    2. 如果没有就创建一个:this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory),并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster

容器中有哪些监听器

  1. 容器创建对象:refresh()
  2. registerListeners()
    1. 从容器中拿到所有的监听器,把他们注册到applicationEventMulticasterString[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false)
    2. listener注册到ApplicationEventMulticastergetApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)

SmartInitializingSingleton原理

@EventListener使用EventListenerMethodProcessor处理器来解析方法上的@EventListenerEventListenerMethodProcessor实现了SmartInitializingSingleton

  1. ioc容器创建对象并refresh()

  2. finishBeanFactoryInitialization(beanFactory):初始化剩下的单实例bean

    1. 先创建所有的单实例bean,getBean()

    2. 获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的

      如果是就调用afterSingletonsInstantiated()

posted @ 2022-05-04 22:49  蔚然丶丶  阅读(114)  评论(0编辑  收藏  举报