Spring全注解开发--扩展原理
Posted 大忽悠爱忽悠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring全注解开发--扩展原理相关的知识,希望对你有一定的参考价值。
扩展原理
BeanFactoryPostProcessor:beanFactory的后置处理器
BeanPostProcessor:bean的后置处理器,bean创建对象初始化前后进行拦截工作的
BeanFactoryPostProcessor:beanFactory的后置处理器,在BeanFactory标准初始化之后调用,来定制和修改BeanFactory里面的内容
所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
继承BeanFactoryPostProcessor 来进行测试:
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
int count = configurableListableBeanFactory.getBeanDefinitionCount();
System.out.println("postProcessBeanFactory执行中...");
System.out.println("bean的数量:"+count);
String[] beans = configurableListableBeanFactory.getBeanDefinitionNames();
System.out.println(Arrays.asList(beans));
}
}
BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}
postProcessBeanDefinitionRegistry
调用时机:在所有bean定义信息将要被加载,bean实例还未创建时
BeanDefinitionRegistry: bean定义信息的保存中心
以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例
实现BeanDefinitionRegistryPostProcessor 接口进行测试:
@Component
public class MyBeanDefinitonRegistry implements BeanDefinitionRegistryPostProcessor {
//BeanDefinitionRegistry: bean定义信息的保存中心
//以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例*
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
//给容器中注册bean
//法1:
// RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(department.class);
//法2:
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(department.class).getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition("depart",beanDefinition);
System.out.println("1.bean的数量:"+beanDefinitionRegistry.getBeanDefinitionCount());
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("2.bean的数量:"+configurableListableBeanFactory.getBeanDefinitionCount());
}
}
ApplicationListener:监听容器中发布的事件,事件驱动模型开发
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E var1);
}
ApplicationListener负责监听ApplicationEvent及其下面的子事件
继承ApplicationListener接口,来监听事件,记得将组件放入容器中:
@Component
public class MyApplicationListener implements ApplicationListener {
//当容器中发布事件后,方法触发
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
System.out.println("收到事件"+applicationEvent);
}
}
默认只会有两个事件,即容器刷新事件和容器关闭事件
或者使用@EventListener注解来定义一个监听器
注:@EventListener(classes={ApplicationEvent.class})中classes监听的类可以是多个,以逗号分开
这里如果使用注解,还是注意当前所在类要加入到容器中
@ComponentScan({"com.config"})
@Configuration
public class MyConfig
{
@EventListener(classes={ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("收到事件"+event);
}
}
自己发布事件:
public class Main
{
//传入的是配置类的位置,一开始是加载配置类,之前是加载配置文件的位置
private static AnnotationConfigApplicationContext ioc= new AnnotationConfigApplicationContext(MyConfig.class);
public static void main(String[] args)
{
//发布事件
ioc.publishEvent(new ApplicationEvent(new String("我发布的一个事件")) {
});
ioc.close();
}
}
原理:
事件:ContextRefreshedEvent、IOCTest_Ext$1[source=我发布的事件]、ContextClosedEvent;
* 1)、ContextRefreshedEvent事件:
* 1)、容器创建对象:refresh();
* 2)、finishRefresh();容器刷新完成会发布ContextRefreshedEvent事件
* 2)、自己发布事件;
* 3)、容器关闭会发布ContextClosedEvent;
*
* 【事件发布流程】源码执行流程:
* 3)、publishEvent(new ContextRefreshedEvent(this));
* 1)、获取事件的多播器(派发器):getApplicationEventMulticaster()
* 2)、multicastEvent派发事件:
* 3)、获取到所有的ApplicationListener;
* for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
* 1)、如果有Executor,可以支持使用Executor进行异步派发;
* Executor executor = getTaskExecutor();
* 2)、否则,同步的方式直接执行listener方法;invokeListener(listener, event);
* 拿到listener回调onApplicationEvent方法;
*
* 【事件多播器(派发器)】源码执行流程:
* 1)、容器创建对象:refresh();
* 2)、initApplicationEventMulticaster();初始化ApplicationEventMulticaster;
* 1)、先去容器中找有没有id=“applicationEventMulticaster”的组件;
* 2)、如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
* 并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster;
*
* 【容器中有哪些监听器】源码执行流程:
* 1)、容器创建对象:refresh();
* 2)、registerListeners();
* 从容器中拿到所有的监听器,把他们注册到applicationEventMulticaster中;
* String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
* //将listener注册到ApplicationEventMulticaster中
* getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
*
* SmartInitializingSingleton 原理:->afterSingletonsInstantiated();
* 1)、ioc容器创建对象并refresh();
* 2)、finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean;
* 1)、先创建所有的单实例bean;getBean();
* 2)、获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;
* 如果是就调用afterSingletonsInstantiated();
*
二、实例
ApplicationListener:监听容器中发布的事件。事件驱动模型开发;
* public interface ApplicationListener<E extends ApplicationEvent>
* 监听 ApplicationEvent 及其下面的子事件;
*
* 步骤:
* 1)、写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类)
* @EventListener;
* 原理:使用EventListenerMethodProcessor处理器来解析方法上的@EventListener;
*
* 2)、把监听器加入到容器;
* 3)、只要容器中有相关事件的发布,我们就能监听到这个事件;
* ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
* ContextClosedEvent:关闭容器会发布这个事件;
* 4)、发布一个事件:
* applicationContext.publishEvent();
以上是关于Spring全注解开发--扩展原理的主要内容,如果未能解决你的问题,请参考以下文章