The title

  • 1. What is the Spring Framework?
  • 2. What are the advantages and disadvantages of the Spring Framework?
  • 3. What is your understanding of IOC?
  • 4. Why is IOC needed?
  • 5. What is the difference between IOC and DI?
  • 6. What are the responsibilities of the IOC container?
  • 7. What is the Spring IOC container?
  • Constructor injection and Setter injection
  • 9. Which is the Spring IoC container, BeanFactory or ApplicationContext?
  • 10. The Spring Bean Lifecycle?
  • 11. What is a BeanDefinition?
  • 12. What are Spring’s built-in Bean scopes?
  • What is the difference between BeanPostProcessor and BeanFactoryPostProcessor?
  • Are the sources of dependency injection and dependency lookup the same?
  • 15. How to extend Spring XML elements based on Extensible XML Authoring?
  • 16. Does Java Generic Erasing occur at compile time or at run time?
  • 17. Describe the mechanism of Spring events?
  • 18. How does @EventListener work?
  • 19. What annotations does Spring provide?
  • 20. Brief introduction of Spring Environment?
  • 21. What is the complete life cycle of Environment?
  • 22. What is the lifecycle of the Spring application context?
  • What are the phases of the Spring application context life cycle?
  • 24. Describe the ObjectFactory?
  • 25. Describe the FactoryBean?
  • What is the difference between ObjectFactory, FactoryBean and BeanFactory?
  • 27. What is the process of @Bean?
  • 28. How does BeanFactory handle cyclic dependencies?
  • 29. What is the execution order of several initialization methods in Spring?

Other Spring topics are also in the codewords, but if you want to see them more quickly, click on the link in the description to get them

Dachang real question + micro-service +MySQL+ distributed +SSM framework +Java+Redis+ data structure and algorithm + network +Linux+Spring + whole family +JVM+ high concurrency + various learning thinking brain map + interview set

1. What is the Spring Framework?

Official document:

Spring makes it easy to create Java enterprise applications. It provides everything you need to embrace the Java language in an enterprise environment, with support for Groovy and Kotlin as alternative languages on the JVM, and with the flexibility to create many kinds of architectures depending on an application’s needs.

This is a hard question to answer, and the official Spring documentation is very abstract. The answer depends on how you understand Spring, and everyone has their own way of answering it. Here is my personal understanding of Spring:

The whole Spring ecosystem is widely used in projects involving Java. It provides a large number of components that make the process of developing Java applications much easier, supports other software frameworks flexibly, and can be likened to a “socket”. Other software frameworks can be simply “plugged in” and used in conjunction with Spring, giving developers a lot of convenience. The design and implementation of the underlying IoC container of Spring is also very perfect. It provides extension points for developers to extend during the entire Spring application context lifecycle and many phases of the Spring Bean lifecycle, making the framework very flexible.

2. What are the advantages and disadvantages of the Spring Framework?

Advantages: Spring is development-oriented, divided according to different functions, and introduced corresponding modules according to requirements. It is very developer-friendly. For example, the Spring IOC container, which manages our Java objects as Spring beans, manages the entire life cycle of the beans. Spring MVC provides a Model-View-Controller architecture and ready-to-use components for developing flexible and loosely coupled Web applications; Spring AOP provides a facet-oriented programming interface, which can be used very easily. There are many other functional modules, I won’t go over them.

Disadvantages: The whole Spring system is relatively complex, which requires a certain learning cost for developers. When encountering relevant problems, developers need to have a full understanding of the underlying implementation, which requires developers to invest more time and energy to learn. Of course, the Spring system now integrates a lot of things in the Java ecology, and the convenience it brings to developers far exceeds these deficiencies. I think it is necessary to fully study Spring and understand the design ideas of Spring’s contributors, which will also improve myself a lot. There’s a lot to learn from it.

3. What is your understanding of IOC?

Inversion of Control (IOC) is a programming idea or principle in Object Oriented. Going back to the traditional way, when I depend on an object, I need to actively create it and assign properties to it before I can use it. With IoC, it makes the creation of objects or components more transparent. You don’t need to worry too much about the details, such as creating objects and assigning properties. These are all done by the IoC container, which has been decoupled.

IoC Inversion of Control (IoC), in simple terms, means that the method of acquiring dependent objects is implemented by the IoC container, changing from “active fetch” to “passive fetch”.

4. Why is IOC needed?

In effect, IOC is designed to mask construction details. For example, all the details of the life cycle of the new object are known to the user. If there is no IOC container, there is no need for the IOC to exist. However, in a complex system, our application should pay more attention to the application of the object, rather than the details of its construction and initialization.

5. What is the difference between IOC and DI?

DI Dependency Injection is not exactly the same as IOC. Rather, DI Dependency Injection is one of the implementation methods or strategies of IOC.

Both dependency lookup and dependency injection are IoC implementation strategies. Dependency lookup is to call the interface provided by the IOC container to obtain the corresponding Bean object in the application program, while dependency injection is to inject the dependency through the constructor, field, setter method or interface, etc. when the IOC container is started or initialized. Dependency lookup is more cumbersome for developers than Dependency Injection. It is code intrusive and requires the use of the interface provided by the IoC container, so we always emphasize the latter. Dependency Injection (DI) is implemented in the IoC container by calling the relevant interface to get the Bean object. However, all of this work is done for you by the container when the IoC container is started. In the application, we rarely call the interface to get the Bean object.

6. What are the responsibilities of the IOC container?

Mainly responsible for the following:

  • Dependency handling, either through dependency lookup or dependency injection
  • Manage the life cycle of managed resources (Java beans or other resources)
  • Management configuration (container configuration, external configuration, managed resource configuration)

There are many IoC containers, such as Java Beans for JDK, EJB for Java EE, Apache Avalon, Google Guice, and Spring. Spring is the most successful one and is widely used today.

Which Spring from the JDK Java Beans design ideas, is to use the related classes (such as Java. Beans. PropertyEditor property editor). Those who have developed GUI interfaces for IDEs should be familiar with Java Beans.

7. What is the Spring IOC container?

Spring framework is an implementation of IoC container, DI dependency injection is a principle of its implementation, provides dependency lookup and dependency injection two kinds of dependency processing, managing the Bean life cycle. Spring also provides AOP abstraction, event abstraction, event listening mechanism, SPI mechanism, strong third-party integration, ease of testing, and more.

Constructor injection and Setter injection

Constructor injection: Injecting dependent objects with constructor arguments

Setter injection: Injecting dependent objects through Setter methods, also known as field injection

Views on the two injection methods:

  • Constructor injection can avoid some awkward problems, such as state uncertainty is changed, the dependent object will be injected when the object is initialized, to a certain extent, to ensure that the Bean is immutable after initialization, which will bring more convenience to our program and maintainability.
  • Constructor injection does not allow cyclic dependencies because it requires that the injected objects be mature enough to be instantiated, whereas Setter injection or field injection does not.
  • Constructor injection can guarantee that dependent objects can be injected in order, while Setter injection or field injection is injected through reflection mechanism, which cannot guarantee the order of injection completely.
  • If there are too many dependencies in constructor injection and the code is not elegant enough, we should consider whether there is a problem with the design of our code and whether we need to refactor the structure of our code.

In addition to the above injection methods, Spring also provides interface callback injection by implementing the Aware interface (e.g., BeannameAware, ApplicationContextAware) to inject related objects. When Spring initializes such beans, it calls its setXXX method to inject objects, such as beanName, applicationContext

9. Which is the Spring IoC container, BeanFactory or ApplicationContext?

The BeanFactory is the underlying IoC container of Spring. ApplicationContext is a subinterface of the BeanFactory and a superset of the BeanFactory, providing more functionality than the IoC container. In addition to playing the role of IOC container, ApplicationContext provides these enterprise features: Aspect Oriented (AOP), Configuration Meta Information, Resource Management, Event Mechanism, Internationalization, Annotations, Environment Abtraction, etc. We generally call ApplicationContext the Spring ApplicationContext and BeanFactory the Spring underlying IoC container.

10. The Spring Bean Lifecycle?

Life cycle:

  1. Spring Bean meta information configuration stage can be configured by resource oriented (XML or Properties), annotation-oriented, and API-oriented
  2. Spring Bean meta information parsing stage, the configuration meta information of the previous step is parsed into a BeanDefinition object, which contains all the information to define the Bean, and is used to instantiate a Spring Bean
  3. Spring Bean meta information registration phase, save the BeanDefinition configuration meta information to the BeanDefinitionRegistry’s ConcurrentHashMap collection
  4. In the Spring BeanDefinition merge stage, the beans defined may have a hierarchical relationship, so they need to be merged, the parent property is overwritten if the same configuration exists, and finally a RootBeanDefinition object is generated
  5. The instantiation phase of the Spring Bean starts by loading a Class object through the Class loader and creating an instance object through the constructor of the Class object. The constructor injection is done here. In the instantiation phase Spring provides two extension points (before and after the instantiation of InstantiationAwareBeanPostProcessor PostProcessBeforeInstantiation, postProcessAfterInstantiation method)
  6. Spring Bean property assignment stage. After Spring instantiation, it is necessary to assign its related properties and inject the dependent objects. You first get the mapping of all the properties of the object to their values, which may be defined or may need to be injected, and are assigned here (reflection mechanism). Just a hint, The realization of the dependency injection through CommonAnnotationBeanPostProcessor (@ Resource, @ PostConstruct, @ PreDestroy) and AutowiredAnnotationBeanPostProcessor (@autowired, @ Value) two processors.
  7. Aware interface callback phase. If the Spring Bean is an Aware interface type provided by Spring (for example, BeannameAware, ApplicationContextAware), the interface callback is performed here. Injecting related objects (such as Beanname, ApplicationContext)
  8. Spring Bean initialization phase, where Spring Bean configuration initialization methods are called in the following order: @PostConstruct annotation method, afterPropertiesSet() method that implements the InitializingBean interface, and custom initialization method. In the initialization phase Spring provides two extension points before and after the initialization (BeanPostProcessor postProcessBeforeInitialization, postProcessAfterInitialization method)
  9. After all the beans (not abstract, singleton, or lazy loading) have been initialized, Spring iterates through all the initialized singleton Bean objects again. SmartInitializingSingleton type is invoked if it is their afterSingletonsInstantiated () method, here also belong to the Spring provides an extension point
  10. Spring Bean destruction phase, when the Spring application context is closed or you actively destroy a Bean to enter the Spring Bean destruction phase, the order of execution: The @PreDestroy annotation destruction action, a callback to the Bean that implements the DisposableBean interface, and the Destroy-Method custom destruction method. There is also a pre-destroy phase, also part of an extension point provided by Spring, on which @PreDestroy is based
  11. Spring Garbage Collection (GC)

Conclusion:

  1. The above1,2,3BeanDefinition belongs to the meta information configuration stage, which is the predecessor of Spring Bean. If you want to generate a Bean object, all the information of this Bean needs to be well defined.
  2. Among them4,5In the instantiation phase, if you want to generate a Java Bean object, you must first instantiate an object based on the meta information of the Bean.
  3. The following6The instantiated object is still an empty object. We need to assign values to all the properties of the object according to the meta information of the Bean.
  4. At the back of the7,8 、9It belongs to the initialization stage. After the Java Bean object is generated, it may need to be initialized before it is used.
  5. The final10,11When the Spring application context shuts down or actively destroys a Bean, you may need to destroy the object and wait for the JVM to reclaim it.

11. What is a BeanDefinition?

BeanDefinition is the “predecessor” of a Spring Bean, which contains all the meta information for initializing a Bean. In the process of initializing a Bean, a Bean object needs to be generated from this object and a series of initialization work needs to be done.

12. What are Spring’s built-in Bean scopes?

source instructions
singleton Default Spring Bean scope, a BeanFactory has one and only one instance
prototype Prototype scope, which generates a new Bean object with each dependency lookup and dependency injection
request Spring beans are stored in the ServletRequest context
session Store Spring beans in HttpSession
application Store the Spring beans in the ServletContext

What is the difference between BeanPostProcessor and BeanFactoryPostProcessor?

BeanPostProcessor provides pre-initialization and post-initialization lifecycle callbacks for Spring beans, allowing extensions and even replacement of beans of interest, and related subclasses also provide callbacks for other phases in the Spring Bean lifecycle.

Spring BeanFactoryPostProcessor provide Spring the BeanFactory (the bottom of the IoC container) lifecycle callback, used to extend the BeanFactory (actual ConfigurableListableBeanFactory), The BeanFactoryPostProcessor must be executed by the Spring ApplicationContext, and the BeanFactory cannot interact with it directly.

Are the sources of dependency injection and dependency lookup the same?

No, the source of Dependency lookup is limited to Spring BeanDefinition and singleton objects, and the source of Dependency injection also includes Resolvable Dependency (an injectable object defined by the Spring application context that can be handled). For example, the injection BeanFactory injects the ApplicationContext object) and the external configuration marked with @Value

15. How to extend Spring XML elements based on Extensible XML Authoring?

The Spring XML extensions

  1. Writing XML Schema files (XSD files) : Define XML structures
  2. Custom NamespaceHandler implementation: The handler that defines the namespace
  3. Custom BeanDefinitionParser implementation: Bind different XML elements in the namespace to their corresponding parsers
  4. Registering XML extensions (META-INF/spring.handlersFile: mapping of the namespace to the namespace handler
  5. Write a Spring Schema resource mapping file (META-INF/spring.schemasAn XML Schema file is usually defined as a network file and cannot be accessed without a network, so there is usually an XSD file locally, which can be written by the XML Schema filespring.schemasFile, which maps the networked XSD file to the local XSD fileGive priority toGet the corresponding XSD file locally

Mybatis to Spring integration project of < Mybatis: scan / > tag is like this, you can refer to: NamespaceHandler, MapperScannerBeanDefinitionParser and XSD files

Refer to the following article “Parsing Custom Tags (XML Files)” for detailed implementation logic

16. Does Java Generic Erasing occur at compile time or at run time?

Runtime. Generic parameter types are still present at compile time and ignored at run time.

17. Describe the mechanism of Spring events?

There are mainly the following roles:

  • The Spring event – org. Springframework. Context. ApplicationEvent, implements the Java. Util. The EventListener interface
  • The Spring event listener – org. Springframework. Context. ApplicationListener, implements the Java. Util. EventObject class
  • The Spring event publishing – org. Springframework. Context. ApplicationEventPublisher
  • Spring event broadcasters – org. Springframework. Context. Event. ApplicationEventMulticaster

Spring built-in events:

  • ContextRefreshedEvent: Spring application context ready event
  • ContextStartedEvent: Spring application context launch event
  • ContextStopPedEvent: Spring application context stop event
  • ContextCloseDevent: Spring application context close event

The Spring application context is a ApplicationEventPublisher event publishing, its internal have a ApplicationEventMulticaster event broadcast (observed), It holds all applicationListener event listeners (observers). Spring application context released after an event will be broadcast via the ApplicationEventMulticaster event broadcast, able to handle the event categories of ApplicationListener event listeners for processing.

18. How does @EventListener work?

@EventListener is used to annotate the method, which can then be used to handle Spring related events.

Spring inside a processor EventListenerMethodProcessor, it implements the SmartInitializingSingleton interface, in all of the beans (not abstract, singleton pattern, not lazy loading mode) after the initialization, Spring executes the handler to process the Bean as it traverses through all the initialized singleton Bean objects again. To mark in the EventListenerMethodProcessor @ EventListener annotation method parse, if eligible to generate an ApplicationListener event listener and register.

19. What annotations does Spring provide?

The core annotations are as follows:

  • Spring schema annotations
The Spring annotations The scene that The initial version
@Repository Data warehousing schema annotations 2.0
@Component Common Component Pattern Annotations 2.5
@Service Service pattern annotations 2.5
@Controller Web Controller pattern annotations 2.5
@Configuration Configure class schema annotations 3.0

Spring schema annotations are derived from @Component. Why does Spring provide so many derived annotations?

The @Component annotation is a generic Component annotation, annotating this annotation indicates that you need to use it as a Spring Bean. Other annotations have their own functions, such as @Controller and its derived annotations for handling HTTP requests in Web scenarios. The @Configuration annotation typically refers to the Spring Bean as a Configuration class and is also provided by CGLIB to help implement AOP features. This is also an idea in Domain Driven Design.

Domain Driven Design: Domain Driven Design (DDD). The system analysis and system design are separate, so not directly the result of the split with the result that demand for design, programming and programming can run code is distorting demand, lead to customer after running software found that a lot of features is not what you want, and the software can’t quickly follow demand change. DDD breaks through this gap, puts forward the concept of domain model, unifies analysis and design programming, and enables software to more flexibly and quickly follow the change of demand.

  • Assembly annotations
The Spring annotations The scene that The initial version
@ImportResource Replacing XML Elements<import> 2.5
@Import Import the Configuration class 2.5
@ComponentScan Scan classes with Spring schema annotations under the specified Package 3.1
  • Dependency Injection annotations
The Spring annotations The scene that The initial version
@Autowired Bean dependency injection, which supports multi-dependency lookup 2.5
@Qualifier Fine-grained @Autowired relies on lookups 2.5
  • @enable module driver
The Spring annotations The scene that The initial version
@EnableWebMvc Start the entire Web MVC module 3.1
@EnableTransactionManagement Start the entire transaction management module 3.1
@EnableCaching Start the entire cache module 3.1
@EnableAsync Start the entire asynchronous processing module 3.1

The @enable module driver is an annotated driver programming model prefixed with @enable. The so-called “module” refers to the set of functional components with the same domain, which is combined to form an independent unit. Examples include Web MVC module, AspectJ proxy module, Caching (Caching) module, JMX (Java Management Extensions) module, Async (asynchronous processing) module, etc.

Such comments the underlying principle is through the @ Import annotations Import related classes (the Configuration Class, ImportSelector interface implementations, ImportBeanDefinitionRegistrar interface implementation), to implement the introduction of a module or function.

  • Conditions of annotation
The Spring annotations The scene that The initial version
@Conditional Conditional to introduce a Bean 4.0
@Profile Starting with Spring 4.0, @profile qualifies the Spring application environment for beans based on the @Conditional implementation 4.0

20. Brief introduction of Spring Environment?

Unifies Spring configuration property storage for placeholder handling and type conversion, and supports richer configuration property sources.

Help the Spring container provide conditional assembly of beans with Environment Profiles information.

21. What is the complete life cycle of Environment?

Before the Spring application context enters the refresh phase, you can set the Environment object in advance through the setEnvironment(Environment) method, If there is no Environment object in the refresh phase, a new Environment object will be created

22. What is the lifecycle of the Spring application context?

The Spring ApplicationContext is the ApplicationContext, Life cycle is mainly manifested in the org. Springframework. Context. Support. AbstractApplicationContext# refresh () method, roughly as follows:

  1. Spring application context startup preparation phase, set the relevant properties, such as startup time, status identifier, Environment object
  2. In the initialization stage of BeanFactory, we initialize a BeanFactory object and load out BeanDefinitions. Set up the relevant components, such as the ClassLoader ClassLoader, expression language processor, property editor, and add several BeanPostProcessor processors
  3. The BeanFactory rear processing phase, mainly performs spring BeanFactoryPostProcessor and BeanDefinitionRegistryPostProcessor processing, Post the BeanFactory and BeanDefinitionRegistry, which belong to an extension point of the Spring application context
  4. The BeanFactory registers the BeanPostProcessor phase and primarily initializes beans of type BeanPostProcessor (dependent lookup) that are seen at many nodes in the Spring Bean life cycle
  5. Initializes the built-in Bean, initialize the current Spring application context MessageSource object (international document related), radio device object, the object of ThemeSource ApplicationEventMulticaster events
  6. Spring event listener registration phase, mainly get all of the applicationListener event listeners registered, and broadcast early events
  7. The BeanFactory initialization phase is completed, which is mainly to initialize all the beans that have not been initialized (not abstract, singleton, not lazy loading).
  8. The Spring application context refresh completion phase clears caches in the current Spring application context, such as metadata scanned by ASM (Java Bytecode Manipulation and Analysis Framework), and publishes context refresh events
  9. AbstractApplicationContext# Spring application context start-up stage, need to take the initiative to call the start () method, which is called all the Lifecycle of the start () method, finally will release the context start events
  10. Spring application context to stop stage, the need to take the initiative to call AbstractApplicationContext# stop () method, which is called all the Lifecycle of the stop () method, the final stop events will release its context
  11. Spring application context closure phase, release the current Spring application context closure event, destroy all singleton beans, close the underlying BeanFactory container; Note that there is a hook function (a thread that Spring registers with the JVM to close the current Spring application context) that triggers the thread to run when the JVM is “closed.

Conclusion:

  • The above1,2,3,4,5,6,7,8Both belong to the refresh stage of Sping application context, which completes a series of initialization work of Spring application context;
  • 9The Spring application context launch phase is associated with Lifecycle objects, whose start() methods are called and the context launch event is published.
  • 10The Spring application context stop phase is associated with Lifecycle objects, whose stop() method is called and the context stop event is published;
  • 11In the Spring application context closure phase, the context closure event is published, all singleton beans are destroyed, and the underlying BeanFactory container is closed.

What are the phases of the Spring application context life cycle?

Refer to the Spring application context lifecycle:

  • The refresh phase – ConfigurableApplicationContext# refresh ()
  • Start-up phase – ConfigurableApplicationContext# start ()
  • Stop phase – ConfigurableApplicationContext# stop ()
  • Closure phase – ConfigurableApplicationContext# close ()

24. Describe the ObjectFactory?

The ObjectFactory (or ObjectProvider) can be associated with a Bean of a type, providing only a getObject() method that returns the target Bean object. When the ObjectFactory object is injected or looked-up, the target Bean object of the associated type is not found in real time. The target Bean object is found only when the getObject() method is called.

Given the nature of the ObjectFactory, it can be said that it provides deferred dependency lookup. This feature is used by Spring in handling cyclic dependencies (field injection), when a Bean is not fully initialized. An ObjectFactory object (whose getObject() method returns the Bean object being initialized) is cached first. If the object that is being initialized depends on the Bean, The Bean currently being initialized is first retrieved from the cached ObjectFactory object, which solves the circular dependency problem.

Note that this is lazy dependency lookup, not lazy initialization. The ObjectFactory cannot determine whether or not the Bean object needs lazy initialization. Instead, we need to configure the Bean’s lazy property to determine whether or not the Bean object needs lazy initialization. Beans that are not lazily initialized are initialized during Spring’s application context refresh.

Tip: If it is the ObjectFactory (or ObjectProvider) type of Bean, when be dependency injection or rely on search returns DefaultListableBeanFactory# DependencyObjectProvider private inner class, ObjectProvider

interface is implemented, and the associated type is Object.

25. Describe the FactoryBean?

FactoryBean associates a Bean object with a getObject() method that returns the target Bean object. When the FactoryBean object is injected or found by a dependency, The actual Bean you get is the Bean object of the target type you get through the getObject() method. If you want to get the factoryBean itself, you can get it by adding &before the beanName.

We can use FactoryBean to help implement complex initialization logic. For example, in a Spring project that integrates MyBatis, how is the Mapper interface injected without implementation classes? The Mapper interface is a FactoryBean object. When you inject the Mapper interface, what you get is a proxy object returned by its getObject() method, through which all database operations are performed.

What is the difference between ObjectFactory, FactoryBean and BeanFactory?

According to their names, they literally mean: Object Factory, Factory Bean

ObjectFactory, FactoryBean, and BeanFactory all provide dependency lookup capabilities.

  • ObjectFactory provides deferred dependency lookup. To get a Bean of a certain type, you need to call its getObject() method to find the target Bean object. An ObjectFactory is an ObjectFactory. To get an object of this type, you need to produce an object by calling its getObject() method.
  • FactoryBean provides no latency. When injected or looked-up, it returns the actual object it gets through the getObject() method. We don’t need to call getObject(). If we want to get the factoryBean itself, we add it in front of the beanName&You can get it.
  • The BeanFactory is the underlying IoC container of Spring, which stores all the singleton beans. ObjectFactory and FactoryBean do not have the ability to rely on lookup by themselves, and the ability is output by the BeanFactory.

27. What is the process of @Bean?

The Spring application context life cycle in the BeanDefinition (@ Component annotations, XML configuration) after the loading, will perform all BeanDefinitionRegistryPostProcessor type of processor, Spring has a ConfigurationClassPostProcessor internal processor, it will be to deal with all the configuration class, Parse its internal annotations (@PropertySource, @ComponentScan, @Import, @ImportResource, @Bean) where the method annotated by the @Bean annotation generates the corresponding BeanDefinition object and registers it. For detailed steps, please refer to the following article: “The IOC article of Spring – Implementing the @Bean annotation”.

28. How does BeanFactory handle cyclic dependencies?

In the foreword, the following “cyclic dependency” is replaced by “cyclic dependency injection”, which is passed in Spring
depends-onA configured dependency object throws an exception if it has a circular dependency

Note: The circular dependency here refers to the circular dependency that occurs when Bean fields are injected in singleton mode. Constructor injection is not automatically resolved for Spring (you should consider whether there is a problem with the code design) and can be handled through lazy initialization. Spring only addresses circular dependencies in the singleton pattern.

The method of handling cyclic dependencies in Spring’s underlying IoC container, BeanFactory, relies mainly on the following three sets of maps:

  1. singletonObjects(Level 1 Map), which holds all the singleton beans that have been initialized, that is, Spring beans that will hold all the singleton beans in the Spring IoC container.
  2. earlySingletonObjects(level 2 Map), which will save fromLevel 3 MapGets the Bean being initialized
  3. singletonFactoriesThe getObject() method returns the Bean object that is being initialized (instantiation is not fully initialized). If it exists, the obtained Bean object is saved to theThe secondary MapWhile from the currentLevel 3 MapRemoves the ObjectFactory implementation class.

When the dependency lookup is done through GetBean, it will first get the above three maps in turn, return them if they exist, and initialize them if they don’t exist. These three maps are the key to deal with cyclic dependencies.

For example, two beans have circular dependencies. A depends on B, and B depends on A. When we go to dependency lookup A, an ObjectFactory object is stored in the singletonFactories above after instantiation and before initialization. The initialization process is injected into B; Next, we need to find B, and when initializing B, we need to inject A and find A again. Since we can get the initializing A directly through the singleTonFactories, we can complete the initialization of B, and finally the initialization of A, so as to avoid cyclic dependency.

Question 1: Why is the above level 2 Map needed?

Because by tertiary Map for Bean will have relevant SmartInstantiationAwareBeanPostProcessor# getEarlyBeanReference (..) To avoid repeated processing, a proxy object may be returned after processing

For example, in A circular dependency, A Bean may be dependent on multiple beans, a-> B (also dependent on A) -> C -> A. When you get the Bean A, then B and C will inject A. There is also a performance gain by holding ObjectFactory implementation classes that are called twice, processed repeatedly, and may cause problems

Question 2: Why don’t you just call the objectFactory #getObject() method and put it in a second-level Map instead of needing the third-level Map above?

For beans that do not involve AOP, it is possible not to need a SingletonFactories (Level 3 Map), but Spring AOP is part of the Spring system. If you do not have a SingletonFactories (Level 3 Map), This means that the Bean will complete the AOP proxying once it is instantiated, which goes against Spring’s design principles. Spring is in completely created through AnnotationAwareAspectJAutoProxyCreator this post processor Bean later completed AOP agent, instead of immediately after the instantiation to AOP agent. If circular dependencies are present, there is nothing to do but create a proxy object for the Bean first, but in the absence of circular dependencies, the design is to allow the Bean to complete the AOP proxy until it is fully created.

Tip: AnnotationAwareAspectJAutoProxyCreator is a rear SmartInstantiationAwareBeanPostProcessor processor, in which the getEarlyBeanReference (..) A proxy object can be created in the. So for the second problem above, if there is a circular dependency, if it is an AOP proxy object, then you can only create the proxy object for the Bean first. The design is to allow the Bean to complete the AOP proxy after it is fully created.

Why is Spring designed to allow beans to complete their AOP proxying after they are fully created?

Because the proxy object created needs to be associated with the target object and the intercepted method needs to be executed against the target object during the intercepting process, it is better for the target object to be “mature” rather than just instantiating an object that has not yet been initialized.

29. What is the execution order of several initialization methods in Spring?

There are the following initialization methods:

  • Aware interface: implements Spring’s relevant XXXAware interfaces, such as BeannameAware and ApplicationContextAware, whose setXXX methods are called back and can be injected into related objects
  • The @PostConstruct annotation: This annotation is a standard JSR-250 annotation, and Spring calls the methods annotated by this annotation
  • InitializingBean interface: Once this interface is implemented, Spring calls its afterPropertiesSet() method
  • Custom initialization methods: Methods specified by init-method are called

The above initialization is performed in the following order during Spring’s initialization process:

  1. AwareA callback to the interface
  2. JSR-250 @PostConstructMethod invocation of the annotation
  3. InitializingBean#afterPropertiesSetMethod callback
  4. init-methodInitializes the method call