ApplicationContextInitializer,ApplicationListener,SpringApplicationRunListener通过SpringFactoriesLoader加载,见《Spring Boot源码阅读分析》
ApplicationListener,和其他Bean也可以通过容器注入(@Component等方式)。
在刷新之前初始化Spring ConfigurableApplicationContext,
方法:
initialize(C applicationContext)
ApplicationContext自动在其bean定义中检测BeanFactoryPostProcessor bean,并在创建任何其他bean之前应用它们。
BeanFactoryPostProcessor可以与bean定义进行交互和修改,但不能与bean实例进行交互。
方法:
/**
*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
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
在BeanFactoryPostProcessor检测开始之前注册更多的bean定义
方法:
//All regular bean definitions will have been loaded, but no beans will have been instantiated yet
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
允许自定义修改新的bean实例—例如,检查标记接口或用代理包装bean。
方法:
//下述2方法调用时,Bean实例只是被创建出来了(例如调用默认的构造函数),还没有设置属性值。
//Apply this BeanPostProcessor to the given new bean instance before any bean initialization callbacks
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//Apply this BeanPostProcessor to the given new bean instance after any bean initialization callbacks
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
BeanPostProcessor的子接口,它在实例化前添加回调,在实例化后但在设置显式属性或发生autowire之前添加回调。
方法:
//before the target bean gets instantiated,via a constructor or factory method default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } //after the bean has been instantiated, via a constructor or factory method default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } /** * Post-process the given property values before the factory applies them * to the given bean, without any need for property descriptors. */ @Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; } /** * Post-process the given property values before the factory applies them * to the given bean. Allows for checking whether all dependencies have been * satisfied, for example based on a "Required" annotation on bean property setters. *
Also allows for replacing the property values to apply, typically through * creating a new MutablePropertyValues instance based on the original PropertyValues, * adding or removing specific values. */ @Deprecated @Nullable default PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; }
Extension of the InstantiationAwareBeanPostProcessor interface, adding a callback for predicting the eventual type of a processed bean.
方法:
/**
* Predict the type of the bean to be eventually returned from this
* processor's
*/
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* Determine the candidate constructors to use for the given bean.
*/
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
/**
* Obtain a reference for early access to the specified bean,
* typically for the purpose of resolving a circular reference.
*/
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
方法:
/**
* Post-process the given merged bean definition for the specified bean.
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
/**
* A notification that the bean definition for the specified name has been reset,
* and that this post-processor should clear any metadata for the affected bean.
*/
default void resetBeanDefinition(String beanName) {
}
Interface to be implemented by application event listeners.
/**
* Handle an application event.
*/
void onApplicationEvent(E event);
/**
* Create a new ApplicationListener for the given payload consumer.
*/
static <T> ApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer) {
return event -> consumer.accept(event.getPayload());
}
Listener for the SpringApplication run method. SpringApplicationRunListeners are loaded via the SpringFactoriesLoader and should declare a public constructor that accepts a SpringApplication instance and a String[] of arguments. A new SpringApplicationRunListener instance will be created for each run.
/**
* Called immediately when the run method has first started. Can be used for very
* early initialization.
*/
default void starting(ConfigurableBootstrapContext bootstrapContext) {
starting();
}
/**
* Called immediately when the run method has first started. Can be used for very
* early initialization.
*/
@Deprecated
default void starting() {
}
/**
* Called once the environment has been prepared, but before the
* ApplicationContext has been created.
*/
default void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
ConfigurableEnvironment environment) {
environmentPrepared(environment);
}
/**
* Called once the environment has been prepared, but before the
* ApplicationContext has been created.
*/
@Deprecated
default void environmentPrepared(ConfigurableEnvironment environment) {
}
/**
* Called once the {@link ApplicationContext} has been created and prepared, but
* before sources have been loaded.
*/
default void contextPrepared(ConfigurableApplicationContext context) {
}
/**
* Called once the application context has been loaded but before it has been
* refreshed.
*/
default void contextLoaded(ConfigurableApplicationContext context) {
}
/**
* The context has been refreshed and the application has started but
* CommandLineRunner CommandLineRunners ApplicationRunner
* ApplicationRunners have not been called.
*/
default void started(ConfigurableApplicationContext context) {
}
/**
* Called immediately before the run method finishes, when the application context has
* been refreshed and all CommandLineRunner CommandLineRunners and
* ApplicationRunner ApplicationRunners have been called.
*/
default void running(ConfigurableApplicationContext context) {
}
/**
* Called when a failure occurs when running the application.
*/
default void failed(ConfigurableApplicationContext context, Throwable exception) {
}
void run(String... args) throws Exception;
void run(ApplicationArguments args) throws Exception;
/**
* Invoked right at the end of the singleton pre-instantiation phase,
* with a guarantee that all regular singleton beans have been created
* already.
*/
void afterSingletonsInstantiated();
注册2个循环引用的Bean
@Component
public class Pet implements SmartInitializingSingleton, InitializingBean, DisposableBean {
String name;
@Autowired
Qee qee ;
@Override
public void destroy() throws Exception {
System.out.println("Pet-(DisposableBean)--【destroy()】");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Pet--(SmartInitializingSingleton)-->【afterSingletonsInstantiated()】");
}
@Override
public void afterSingletonsInstantiated() {
System.out.println("Pet---->【afterSingletonsInstantiated()】");
}
Pet(){
System.out.println("Pet------>【Pet()无参构造器】");
System.out.println("Pet.qee==["+qee+"]");
}
public Pet(String name,Qee qee) {
System.out.println("Pet------>【Pet()】有参构造器");
this.name = name;
this.qee = qee;
}
public Qee getQee() {
return qee;
}
@PostConstruct
public void Beaninit(){
System.out.println("Pet---(@PostConstruct)---->【Beaninit()】");
System.out.println("Pet.qee==["+qee+"]");
}
@PreDestroy
public void Beandestory(){
System.out.println("Pet---(@PreDestroy)---->【Beandestory()】");
}
}
public class Qee {
@Autowired
Pet pet;
Qee(){
System.out.println("Qee-----【Qee()】无参构造器");
System.out.println("Qee.pet==["+pet+"]");
}
@PostConstruct
public void Beaninit(){
System.out.println("Qee------【Beaninit()】");
System.out.println("Qee.pet==["+pet+"]");
}
public Pet getPet( ) {
return pet;
}
}
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
public MyBeanDefinitionRegistryPostProcessor() {
System.out.println("MyBeanDefinitionRegistryPostProcessor------>【初始化】");
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor------>【postProcessBeanDefinitionRegistry()】");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
System.out.println("MyBeanFactoryPostProcessor---【初始化】");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor---->【postProcessBeanFactory()】");
}
}
只判断BeanName=="qee"或者"pet"才打印,不然会把其他系统的bean信息也打印出来。
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
System.out.println("MyBeanPostProcessor--【初始化】");
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("pet")||beanName.equals("qee"))
System.out.println("MyBeanPostProcessor--------->【postProcessAfterInitialization("+beanName+")】");
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("pet")||beanName.equals("qee"))
System.out.println("MyBeanPostProcessor--------->【postProcessBeforeInitialization("+beanName+")】");
return bean;
}
}
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
public MyInstantiationAwareBeanPostProcessor() {
System.out.println("MyInstantiationAwareBeanPostProcessor---【初始化】");
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if(beanName.equals("pet")||beanName.equals("qee"))
System.out.println("MyInstantiationAwareBeanPostProcessor--------->【postProcessBeforeInstantiation("+beanName+")】");
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if(beanName.equals("pet")||beanName.equals("qee"))
System.out.println("MyInstantiationAwareBeanPostProcessor--------->【postProcessAfterInstantiation("+beanName+")】");
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if(beanName.equals("pet")||beanName.equals("qee"))
System.out.println("MyInstantiationAwareBeanPostProcessor--------->【postProcessProperties("+beanName+")】");
return null;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
if(beanName.equals("pet")||beanName.equals("qee"))
System.out.println("MyInstantiationAwareBeanPostProcessor--------->【postProcessPropertyValues("+beanName+")】");
return pvs;
}
}
public class myMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
public myMergedBeanDefinitionPostProcessor() {
System.out.println("myMergedBeanDefinitionPostProcessor----【初始化】");
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if(beanName.equals("pet")||beanName.equals("qee"))
System.out.println("myMergedBeanDefinitionPostProcessor--------->【postProcessMergedBeanDefinition("+beanName+")】");
}
@Override
public void resetBeanDefinition(String beanName) {
if(beanName.equals("pet")||beanName.equals("qee"))
System.out.println("myMergedBeanDefinitionPostProcessor--------->【resetBeanDefinition("+beanName+")】");
}
}
public class myApplicationContextInitializer implements ApplicationContextInitializer {
public myApplicationContextInitializer() {
System.out.println("myApplicationContextInitializer----【初始化】");
}
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("myApplicationContextInitializer---------【initializer()】");
}
}
public class MyApplicationListener implements ApplicationListener{
public MyApplicationListener() {
System.out.println("MyApplicationListener--【初始化】");
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("MyApplicationListener----【onApplicationEvent】");;
}
}
public class MySpringApplicationRunListener implements SpringApplicationRunListener {
SpringApplication springApplication;
String [] strings;
public MySpringApplicationRunListener(SpringApplication springApplication,String [] strings) {
System.out.println("MySpringApplicationRunListener----【初始化】");
this.springApplication = springApplication;
this.strings = strings;
}
@Override
public void starting(ConfigurableBootstrapContext bootstrapContext) {
System.out.println("MySpringApplicationRunListener【starting()】");
}
@Override
public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
System.out.println("MySpringApplicationRunListener【environmentPrepared()】");
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
System.out.println("MySpringApplicationRunListener【contextPrepared()】");
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
System.out.println("MySpringApplicationRunListener【contextLoaded()】");
}
@Override
public void started(ConfigurableApplicationContext context) {
System.out.println("MySpringApplicationRunListener【started()】");
}
@Override
public void running(ConfigurableApplicationContext context) {
System.out.println("MySpringApplicationRunListener【running()】");
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
System.out.println("MySpringApplicationRunListener【failed()】");
}
}
public class myApplicationRunner implements ApplicationRunner {
public myApplicationRunner() {
System.out.println("myApplicationRunner---->【初始化】");
}
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("myApplicationRunner----【run("+args.toString()+")】");
}
}
public class myCommandLineRunner implements CommandLineRunner {
public myCommandLineRunner() {
System.out.println("myCommandLineRunner---->【初始化】");
}
@Override
public void run(String... args) throws Exception {
System.out.println("myCommandLineRunner--->【run("+args+")】");
}
}
# ApplicationListener
org.springframework.context.ApplicationListener=\
com.keepromise.Listener.MyApplicationListener
# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
com.keepromise.Listener.MySpringApplicationRunListener
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
com.keepromise.Initializer.myApplicationContextInitializer
public class Main {
public static void main(String[] args) {
//返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(Main.class, args);
Pet pet = run.getBean(Pet.class);
Qee qee = run.getBean(Qee.class);
System.out.println(qee.getPet()==pet);
System.out.println(qee==pet.getQee());
}
}
注://符号为注释,复制控制台内容加入一些说明。
//-----ApplicationContextInitializer,ApplicationListener,SpringApplicationRunListener的初始化。-----------
myApplicationContextInitializer----【初始化】
MyApplicationListener--【初始化】
MySpringApplicationRunListener----【初始化】
//-----触发事件,容器正在启动starting--------------------------------------------------------------------------
MyApplicationListener----【onApplicationEvent】
MySpringApplicationRunListener【starting()】
//-----触发事件,准备环境-------------------------------------------------------------------------------------
MyApplicationListener----【onApplicationEvent】
MySpringApplicationRunListener【environmentPrepared()】
//-----打印Spring boot标记----------------------------------------------------------------------------------
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.2)
//-----调用ApplicationContextInitializer.initializer()方法---------------------------------------------------
myApplicationContextInitializer---------【initializer()】
//触发事件,contextPrepared----------------------------------------------------------------------------------
MyApplicationListener----【onApplicationEvent】
MySpringApplicationRunListener【contextPrepared()】
2021-02-10 16:36:43.331 INFO 1964 --- [ main] com.keepromise.Main : Starting Main using Java 1.8.0_144 on LAPTOP-LS49EQBH with PID 1964 (D:\C\Java\mavenProject\Springboot\target\classes started by KeePromise in D:\C\Java\mavenProject\Springboot)
2021-02-10 16:36:43.336 INFO 1964 --- [ main] com.keepromise.Main : No active profile set, falling back to default profiles: default
//触发事件,contextLoaded-------------------------------------------------------------------------------------
MyApplicationListener----【onApplicationEvent】
MySpringApplicationRunListener【contextLoaded()】
//源码invokeBeanFactoryPostProcessors()调用,见《Spring boot源码阅读分析》该函数----------------------------------
MyBeanDefinitionRegistryPostProcessor------>【初始化】
MyBeanDefinitionRegistryPostProcessor------>【postProcessBeanDefinitionRegistry()】
MyBeanFactoryPostProcessor---【初始化】
MyBeanFactoryPostProcessor---->【postProcessBeanFactory()】
//源码registerBeanPostProcessors(beanFactory)调用,见《Spring boot源码阅读分析》该函数---------------------------
//初始化所有的BeanPostProcessor.class
MyBeanPostProcessor--【初始化】
MyInstantiationAwareBeanPostProcessor---【初始化】
myMergedBeanDefinitionPostProcessor----【初始化】
//源码finishBeanFactoryInitialization()调用,见《Spring boot源码阅读分析》该函数---------------------------------
//初始化剩余的所有的Bean
myApplicationRunner---->【初始化】
myCommandLineRunner---->【初始化】
//接下来可以看出如何解决的循环依赖问题,详细见《Spring Boot getBean()》
//1.InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(),对pet进行处理,证明首先想要实例化pet对象
MyInstantiationAwareBeanPostProcessor--------->【postProcessBeforeInstantiation(pet)】
//调用了pet的无参构造器,实例化该对象。
Pet------>【Pet()无参构造器】
//调用完成后,此时内部的变量qee还是null。
Pet.qee==[null]
//2.MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),继续对初始化后的pet进行处理
myMergedBeanDefinitionPostProcessor--------->【postProcessMergedBeanDefinition(pet)】
//3.InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(),继续对初始化后的pet进行处理
MyInstantiationAwareBeanPostProcessor--------->【postProcessAfterInstantiation(pet)】
//4.上述3.返回true则调用InstantiationAwareBeanPostProcessor.postProcessProperties(),继续对初始化后的pet进行处理
MyInstantiationAwareBeanPostProcessor--------->【postProcessProperties(pet)】
//5.上述4.返回null则调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues(),继续对初始化后的pet进行处理
MyInstantiationAwareBeanPostProcessor--------->【postProcessPropertyValues(pet)】
//最后会调用一个系统的InstantiationAwareBeanPostProcessor,用来处理@Autowire注入。对初始化后的pet进行依赖注入。
//它判断pet依赖qee,所以去getBean(Qee.class),详细见《Spring Boot getBean()》[返回点]
//同上1.->5. 对pet的处理一样对qee进行处理,1->5都发生在对一个Bean的getBean()方法中。
MyInstantiationAwareBeanPostProcessor--------->【postProcessBeforeInstantiation(qee)】//同1
//初始化qee
Qee-----【Qee()】无参构造器
//此时内部pet还是null,虽然此时已经初始化好pet了,但是同上面一样,依赖注入要靠系统的InstantiationAwareBeanPostProcessor。
Qee.pet==[null]
myMergedBeanDefinitionPostProcessor--------->【postProcessMergedBeanDefinition(qee)】//同2.
MyInstantiationAwareBeanPostProcessor--------->【postProcessAfterInstantiation(qee)】//同3.
MyInstantiationAwareBeanPostProcessor--------->【postProcessProperties(qee)】//同4.
MyInstantiationAwareBeanPostProcessor--------->【postProcessPropertyValues(qee)】//同5.
//调用BeanPostProcessor.postProcessBeforeInitialization()方法,对qee进行处理。
MyBeanPostProcessor--------->【postProcessBeforeInitialization(qee)】
//调用Beaninit()方法。
Qee------【Beaninit()】
//此时pet依赖已经注入。
Qee.pet==[com.keepromise.bean.Pet@70f02c32]
//该qee实例化完成,调用BeanPostProcessor.postProcessAfterInitialization(),对qee进行处理。
MyBeanPostProcessor--------->【postProcessAfterInitialization(qee)】
//getBean(Qee.class)返回到上面的 [返回点],并且返回qee实例。
//此时依赖的qee已经初始化好,说明pet的依赖已经准备好了。
//调用BeanPostProcessor.postProcessBeforeInitialization(),对pet进行处理
MyBeanPostProcessor--------->【postProcessBeforeInitialization(pet)】
//调用@PostConstruct注解的方法Beaninit()
Pet---(@PostConstruct)---->【Beaninit()】
//此时qee也已经注入pet中了。
Pet.qee==[com.keepromise.bean.Qee@7b205dbd]
//调用接口InitializingBean.afterPropertiesSet()
Pet-(InitializingBean)--【afterPropertiesSet()】
//调用BeanPostProcessor.postProcessAfterInitialization(),对pet进行处理
MyBeanPostProcessor--------->【postProcessAfterInitialization(pet)】
//调用接口SmartInitializingSingleton的afterSingletonsInstantiated()方法
Pet--(SmartInitializingSingleton)-->【afterSingletonsInstantiated()】
//所有单例非懒初始化的Bean实例化完成。
//触发事件,started-------------------------------------------------------------------------------------------
MyApplicationListener----【onApplicationEvent】
2021-02-10 16:36:44.258 INFO 1964 --- [ main] com.keepromise.Main : Started Main in 1.578 seconds (JVM running for 3.204)
MyApplicationListener----【onApplicationEvent】
MyApplicationListener----【onApplicationEvent】
MySpringApplicationRunListener【started()】
//调用Runner.run()方法。
myApplicationRunner----【run(org.springframework.boot.DefaultApplicationArguments@77258e59)】
myCommandLineRunner--->【run([Ljava.lang.String;@5dcd8c7a)】
//触发事件,running-------------------------------------------------------------------------------------------
MyApplicationListener----【onApplicationEvent】
MyApplicationListener----【onApplicationEvent】
MySpringApplicationRunListener【running()】
//main()方法输出,看到注入的依赖正确。
true
true
MyApplicationListener----【onApplicationEvent】
//程序退出,调用@PreDestroy注解的Beandestory()方法。
Pet---(@PreDestroy)---->【Beandestory()】
//然后调用接口DisposableBean的destroy()方法。
Pet-(DisposableBean)--【destroy()】
Process finished with exit code 0
Spring Boot对单实例Bean的实例化,几乎都是通过方法getBean()实现。
此处的Bean包括(除去从spring.factories中读取,和自行实例化的)所有的单例非懒加载的Bean。
Spring Boot通过此方法的递归调用,实现对循环依赖的注入。
Bean可以分为初始化和实例化2中状态:
假如:
A------->B-------->A
且先调用getBean(A)。
则:
getBean(A)------------------->getBean(B)--------------------------->getBean(A) [此时A已经初始化,把A的引用注入B,B实例化完成]
B实例化完成后,A中自然可以注入B的引用值。
所以:
虽然系统先对A调用getBean,但是B先被实例化。