spring注解驱动(扩展原理):BeanFactoryPostProcessor及子接口,ApplicationListener,@EventListener

扩展原理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]; root of context hierarchy

原码查看

首先还是创建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();

猜你喜欢

转载自blog.csdn.net/qq_43416157/article/details/108434074