Spring Boot 常用接口和调用顺序,以及循环依赖分析

文章目录

  • Spring Boot 常用接口和调用顺序,以及循环依赖分析
      • 1.概述
          • 1.ApplicationContextInitializer
          • 2.BeanFactoryPostProcessor
          • 2.1 BeanDefinitionRegistryPostProcessor
          • 3.BeanPostProcessor
          • 3.1InstantiationAwareBeanPostProcessore
          • 3.1.1 SmartInstantiationAwareBeanPostProcessor
          • 3.2 MergedBeanDefinitionPostProcessor
          • 4.ApplicationListener
          • 5.SpringApplicationRunListener
          • 6.CommandLineRunner
          • 7.ApplicationRunner
          • 8.SmartInitializingSingleton
      • 2.调用顺序
          • 1.构造所有的测试类
          • 1.1Bean
          • 1.2BeanFactoryPostProcessor
          • 1.3BeanPostProcessor
          • 1.4ApplicationContextInitializer
          • 1.5 ApplicationListener
          • 1.6SpringApplicationRunListener
          • 1.7Runner
          • 2.配置spring.factories
          • 3.Main
          • 4.输出和分析
      • 3.循环依赖处理

Spring Boot 常用接口和调用顺序,以及循环依赖分析

1.概述

ApplicationContextInitializer,ApplicationListener,SpringApplicationRunListener通过SpringFactoriesLoader加载,见《Spring Boot源码阅读分析》

ApplicationListener,和其他Bean也可以通过容器注入(@Component等方式)。

1.ApplicationContextInitializer

在刷新之前初始化Spring ConfigurableApplicationContext,

方法:

initialize(C applicationContext)
2.BeanFactoryPostProcessor

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;
2.1 BeanDefinitionRegistryPostProcessor

在BeanFactoryPostProcessor检测开始之前注册更多的bean定义

方法:

//All regular bean definitions will have been loaded, but no beans will have been instantiated yet
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
3.BeanPostProcessor

允许自定义修改新的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;
}
3.1InstantiationAwareBeanPostProcessore

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; }

3.1.1 SmartInstantiationAwareBeanPostProcessor

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;
}
3.2 MergedBeanDefinitionPostProcessor

方法:

/**
 * 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) {
     
}
4.ApplicationListener

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());
}
5.SpringApplicationRunListener

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) {
     
}
6.CommandLineRunner
void run(String... args) throws Exception;
7.ApplicationRunner
void run(ApplicationArguments args) throws Exception;
8.SmartInitializingSingleton
/**
 * 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.调用顺序

1.构造所有的测试类
1.1Bean

注册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;
    }
}
1.2BeanFactoryPostProcessor
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()】");
    }
}
1.3BeanPostProcessor

只判断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+")】");
    }
}
1.4ApplicationContextInitializer
public class myApplicationContextInitializer implements ApplicationContextInitializer {
     

    public myApplicationContextInitializer() {
     
        System.out.println("myApplicationContextInitializer----【初始化】");
    }

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
     
        System.out.println("myApplicationContextInitializer---------【initializer()】");
    }
}
1.5 ApplicationListener
public class MyApplicationListener implements ApplicationListener{
     
    public MyApplicationListener() {
     
        System.out.println("MyApplicationListener--【初始化】");
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
     
        System.out.println("MyApplicationListener----【onApplicationEvent】");;
    }
}
1.6SpringApplicationRunListener
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()】");
    }
}
1.7Runner
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+")】");
    }
}
2.配置spring.factories
# 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
3.Main
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());
    }
}
4.输出和分析

注://符号为注释,复制控制台内容加入一些说明。

//-----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

3.循环依赖处理

Spring Boot对单实例Bean的实例化,几乎都是通过方法getBean()实现。

此处的Bean包括(除去从spring.factories中读取,和自行实例化的)所有的单例非懒加载的Bean。

Spring Boot通过此方法的递归调用,实现对循环依赖的注入。

Bean可以分为初始化和实例化2中状态:

  • 初始化:表示该Bean的属性此时只是默认值。
  • 实例化:表示该Bean的属性值被填充。

假如:

A------->B-------->A

且先调用getBean(A)。

则:

getBean(A)------------------->getBean(B)--------------------------->getBean(A) [此时A已经初始化,把A的引用注入B,B实例化完成]

B实例化完成后,A中自然可以注入B的引用值。

所以:

虽然系统先对A调用getBean,但是B先被实例化。

你可能感兴趣的:(SpringBoot,java,spring,spring,boot)