案例准备
创建项目spring-extension
- pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ittzg</groupId>
<artifactId>spring-extension</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<priject.build.sourceEncoding>UTF-8</priject.build.sourceEncoding>
<maven.complier.source>1.8</maven.complier.source>
<maven.complier.target>1.8</maven.complier.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
- 项目结构
一、BeanFactoryPostProcessor
- 源码
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* 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.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
//在该类初始化之后,更新应用容器中的bean工厂;此时所有bean的定义信息将被加载,但是却没有实例化的;
//它将允许bean的属性值被修改,也可提前初始化bean
//注意:实现改接口的类@Value的属性注入将会失效
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
- 案例
=================================User.java===============================
@Component
public class User {
public User() {
System.out.println("--------User-----初始化--------");
}
}
===================MyBeanFactoryPostProcessor.java======================
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Value("zhangsan")
private String name;
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("---------MyBeanFactoryPostProcessor--postProcessBeanFactory---");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
=============================ConfigBean.java==========================
@Configuration
@ComponentScan(value = "com.ittzg.bean")
public class ConfigBean {
}
=========================MainTest.java================================
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext =
new AnnotationConfigApplicationContext(ConfigBean.class);
MyBeanFactoryPostProcessor myBeanFactoryPostProcessor = annotationConfigApplicationContext.getBean(MyBeanFactoryPostProcessor.class); System.out.println("myBeanFactoryPostProcessor:name="+myBeanFactoryPostProcessor.getName());
annotationConfigApplicationContext.close();
}
}
=========================输出结果================================
---------MyBeanFactoryPostProcessor--postProcessBeanFactory---
--------User-----初始化--------
myBeanFactoryPostProcessor:name=null
二、BeanDefinitionRegistryPostProcessor
- 实现该接口的bean的方法执行时间将在实现BeanFactoryPostProcessor的bean的方法执行之前
- 案例
==============MyBeanDefinitionRegistryPostProcessor.java=================
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
System.out.println("---------MyBeanDefinitionRegistryPostProcessor--postProcessBeanDefinitionRegistry---");
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("---------MyBeanDefinitionRegistryPostProcessor--postProcessBeanFactory---");
}
}
=========================输出结果================================
---------MyBeanDefinitionRegistryPostProcessor--postProcessBeanDefinitionRegistry---
---------MyBeanDefinitionRegistryPostProcessor--postProcessBeanFactory---
---------MyBeanFactoryPostProcessor--postProcessBeanFactory---
--------User-----初始化--------
myBeanFactoryPostProcessor:name=null
- 源码解析实现BeanDefinitionRegistryPostProcessor的bean的方法为什么会在实现BeanFactoryPostProcessor的bean的方法执行之前
- AnnotationConfigApplicationContext的创建时需要调用构造
- debug获取方法调用栈
- 有上述方法调用栈,我们可以得出BeanDefinitionRegistryPostProcessor的调用时机是在执行invokeBeanFactoryPostProcessors:286, PostProcessorRegistrationDelegate (org.springframework.context.support)该方法的时候发生的我们接下来查看源码
- 由于方法内容较多我们截取需要的片段
- 有上述可知实现BeanDefinitionRegistryPostProcessor的bean的方法为什么会在实现BeanFactoryPostProcessor的bean的方法执行之前
三、ApplicationListener
- 源码
//函数式接口
//容器的事件的监听
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E event);
}
- 案例
public class MyApplicationListener implements ApplicationListener {
public void onApplicationEvent(ApplicationEvent applicationEvent) {
System.out.println("收到事件:"+applicationEvent);
}
}
=====输出
---------MyBeanDefinitionRegistryPostProcessor--postProcessBeanDefinitionRegistry---
---------MyBeanDefinitionRegistryPostProcessor--postProcessBeanFactory---
---------MyBeanFactoryPostProcessor--postProcessBeanFactory---
--------User-----初始化--------
收到事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@300ffa5d, started on Fri May 17 00:15:48 GMT+08:00 2019]
myBeanFactoryPostProcessor:name=null
收到事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@300ffa5d, started on Fri May 17 00:15:48 GMT+08:00 2019]
- ApplicationListener执行源码分析 方法调用栈
- 执行流程
- 创建容器
- 调用refresh()刷新容器,在该方法中调用finishRefresh()
- publishEvent()给容器注册事件
- multicastEvent调用多博器执行invokeListener方法,完成ApplicationListener.onApplicationEvent()方法的执行
四、 @EventListener
- @EventListener的功能和完成ApplicationListener的功能相同使用方法如下
@Service
public class UserService {
public UserService() {
System.out.println("--------UserService-----初始化--------");
}
@EventListener(value = {ApplicationEvent.class})
public void listenEvent(ApplicationEvent event){
System.out.println("收到事件:"+event);
}
}
=======
---------MyBeanDefinitionRegistryPostProcessor--postProcessBeanDefinitionRegistry---
---------MyBeanDefinitionRegistryPostProcessor--postProcessBeanFactory---
---------MyBeanFactoryPostProcessor--postProcessBeanFactory---
--------User-----初始化--------
--------UserService-----初始化--------
收到事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@300ffa5d, started on Fri May 17 00:30:07 GMT+08:00 2019]
myBeanFactoryPostProcessor:name=null
收到事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@300ffa5d, started on Fri May 17 00:30:07 GMT+08:00 2019]