spring注解驱动开发——扩展原理(三)

BeanFactoryPostProcessor

https://blog.csdn.net/weixin_42412601/article/details/104032552

BeanDefinitionRegistryPostProcessor

BeanFactoryPostProcessor的子接口,bean定义注册中心的后置处理器。
提供一个方法postProcessBeanDefinitionRegistry执行时机:在ioc容器初始化后,beanDefinition将要被加载,优先于BeanFactoryPostProcessor执行,注意:BeanFactoryPostProcessorpostProcessBeanFactory方法是在beanDefinition加载完后,但是bean还没实例化之前执行。

自定义BeanDefinitionRegistryPostProcessor

@Component
public class MyBeanDefinitionRegisterPostProcessor implements BeanDefinitionRegistryPostProcessor {
    //BeanDefinitionRegistry bean定义的保存中心
    //以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("MyBeanDefinitionRegisterPostProcessor...postProcessBeanDefinitionRegistry");
        System.out.println("bean定义数量:"+registry.getBeanDefinitionCount());
        //手动注册一个Bean
//        RootBeanDefinition rootBeanDefinition=new RootBeanDefinition(Car.class);
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Car.class).getBeanDefinition();
        registry.registerBeanDefinition("hello",beanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("MyBeanDefinitionRegisterPostProcessor...postProcessBeanFactory");
        System.out.println("bean定义数量:"+beanFactory.getBeanDefinitionCount());

    }
}
    @Test
    public  void test(){
        AnnotationConfigApplicationContext applicationContext=
                new AnnotationConfigApplicationContext(ExtConfig.class);
        applicationContext.close();
    }
MyBeanDefinitionRegisterPostProcessor...postProcessBeanDefinitionRegistry
bean定义数量:9
MyBeanDefinitionRegisterPostProcessor...postProcessBeanFactory
bean定义数量:10
MyBeanFactoryPostProcessor...postProcessBeanFactory
当前BeanFactory中有BeanDefinition:10个
[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, extConfig, myBeanDefinitionRegisterPostProcessor, myBeanFactoryPostProcessor, car, hello]
Car constructor....
Car constructor....

BeanDefinitionRegistryPostProcessor原理

1、ioc创建对象;
2、refresh() -》invokeBeanFactoryPostProcessors(beanFactory);
3、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件。

String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

(1)、按照优先级依次触发所有的postProcessBeanDefinitionRegistry()方法;

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

(2)、再来触发postProcessBeanFactory()方法BeanFactoryPostProcessor;

	// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
	invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);

4、再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法。

ApplicationListener

监听容器中发布的事件,事件驱动模型开发。public interface ApplicationListener extends EventListener
监听ApplicationEvent及其下面的子事件

只要容器中有相应事件的发布,我们就能监听到这个事件;
 ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
 ContextClosedEvent:关闭容器会发布这个事件;

自定义监听器:通过实现ApplicationListener接口来自定义监听器

@Component
public class MyApplicationListener implements ApplicationListener {
    //当容器中发布此事件,方法触发
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("收到事件:"+event);
    }
}

自定义监听器方式二:注解的方式@EventListener

@Service
public class UserService {
    //监听的事件类型
    @EventListener(classes = {ApplicationEvent.class})
    public void  listen(ApplicationEvent applicationEvent){
        //入参拿到的事件
        System.out.println("UserService监听到的事件:"+applicationEvent);
    }
}

测试:

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

结果:这里监听到了三个事件,容器刷新完成事件,自己发布的事件,容器关闭事件

收到事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@7907ec20, started on Sat Jan 18 22:01:55 CST 2020]
收到事件:spring.kz.kzTest$1[source=我发布的事件]
收到事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@7907ec20, started on Sat Jan 18 22:01:55 CST 2020]

ApplicationListener原理

ContextRefreshedEvent,kzTest$1[source=我发布的事件],ContextClosedEvent
1.ContextRefreshedEvent事件
1.1容器创建对象:refresh();
1.2finishRefresh();容器刷新完成会发布ContextRefreshedEvent事件
事件发布流程:
1.3publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件
1.3.1获取事件的多播器(派发器):getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);多播器就是把事件发给多个监听器
1.3.2multicastEvent(applicationEvent, eventType);派发事件
1.3.3获取所有的getApplicationListeners

for (final ApplicationListener listener : getApplicationListeners(event, type)) 
如果有Executor,可以支持使用Executor进行异步派发,Executor executor = getTaskExecutor();
否则使用同步的方式直接执行invokeListener(listener, event);

1.3.4执行Listener invokeListener(listener, event);
listener.onApplicationEvent(event);拿到listener回调onApplicationEvent方法

2.自己发布的事件 事件发布流程同上
3.容器关闭发布ContextClosedEvent 事件发布流程同上

applicationContext.close()>doClose()->publishEvent(new ContextClosedEvent(this));

事件的多播器是怎么获取的呢?
1.容器创建对象:refresh()
2.initApplicationEventMulticaster();初始化ApplicationEventMulticaster
2.1先去容器中找有没有自定义的id="applicationEventMulticaster"的组件

if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);

有直接创建bean,赋值,初始化
2.2如果没有,自己手动创建并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster组件

else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);

容器中有哪些监听器
1.容器创建对象:refresh()
2.registerListeners(); 注册监听器
2.1从容器中获取所有的监听器定义,把它们注册到applicationEventMulticaster多播器组件中

String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
	getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}

自定义多播器:

https://blog.csdn.net/pengweismile/article/details/92363266

@EventListener原理

使用EventListenerMethodProcessor处理器来解析方法上的@EventListener;该处理器实现了SmartInitializingSingleton接口,该接口的afterSingletonsInstantiated方法,执行时机为所有的单实例bean创建完之后。
SmartInitializingSingleton原理:
1.ioc容器创建并refresh()
2.finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean-》preInstantiateSingletons()
2.1先创建所有的单实例bean:遍历所有的beanDefinition,然后getBean(beanName);创建对象
2.2遍历创建好的所有的单实例bean,判断是否实现了SmartInitializingSingleton,如果是调用smartSingleton.afterSingletonsInstantiated();

for (String beanName : beanNames) {
	Object singletonInstance = getSingleton(beanName);
	if (singletonInstance instanceof SmartInitializingSingleton) {
		final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				smartSingleton.afterSingletonsInstantiated();
				return null;
			}, getAccessControlContext());
		}
		else {
			smartSingleton.afterSingletonsInstantiated();
		}
	}
}

你可能感兴趣的:(spring)