Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to gain an in-depth understanding of Spring's Bean life cycle

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article shows you how to gain an in-depth understanding of Spring's Bean life cycle, which is concise and easy to understand, which will definitely brighten your eyes. I hope you can gain something through the detailed introduction of this article.

What is the life cycle of Spring Bean

For ordinary Java objects, an object is created when new, and then the object can be used. Once the object is no longer in use, Java automatically collects the garbage.

The object in Spring is bean,bean and ordinary Java object is not much different, but Spring no longer go to new object, but by the IoC container to help us instantiate the object and manage it, which object we need, just ask the IoC container for it. IoC is to solve the problem of coupling between objects, and the life cycle of Spring Bean is completely controlled by the container.

Life cycle of Bean

The lifecycle phases of Spring bean are:

1.bean definition: loads and reads the meta-information of bean from xml or annotation location resources and defines it as a BeanDefinition object

2.bean registration: put the BeanDefinition object into the cache pool map according to the appropriate rules

3. Instantiate: instantiate the real bean according to BeanDefinition, that is, call the constructor

4. Dependency injection: property assignment calls the setter method, that is, dependency injection (DI)

5. Initialization: initialization is a stage in which users can customize the extension

6. Destroy: destroy is a stage in which the user can customize the extension

Note: others are extension points before and after this stage.

View the definition and registration of bean from the perspective of Spring

Refresh ()

Public void refresh () throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start ("spring.context.refresh"); / / prepare Bean initialization related environment information. An empty initPropertySources () method is provided internally to provide the user with an opportunity to change the relevant environment information this.prepareRefresh () / / create an BeanFactory instance and register the relevant bean information ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory (); / / register the Aware and Processor instances, and register some Editor information this.prepareBeanFactory (beanFactory) required for subsequent processing of the request An empty method provided by try {/ / for subclasses to customize this.postProcessBeanFactory (beanFactory) for some information about the generated BeanFactory; StartupStep beanPostProcess = this.applicationStartup.start ("spring.context.beans.post-process") / call the relevant methods of BeanFactoryPostProcessor and its subinterfaces, which provide the caller with an entry this.invokeBeanFactoryPostProcessors (beanFactory) to modify the generated BeanDefinition; / / a pair of BeanPostProcessor to register this.registerBeanPostProcessors (beanFactory); beanPostProcess.end () / / initialize the bean information this.initMessageSource () required for internationalization; / / initialize the bean information this.initApplicationEventMulticaster () of the event broadcaster; / / provide an empty method for subclasses to provide custom bean information, or modify existing bean information this.onRefresh () / / register the event listener this.registerListeners (); / / A pair of instantiated this.finishBeanFactoryInitialization (beanFactory) of the registered non-latency (specified by the configuration file) bean; / / clear the cached resource information, initialize some bean related to the declaration cycle, and publish the event this.finishRefresh that the Context has been initialized () } catch (BeansException var10) {if (this.logger.isWarnEnabled ()) {this.logger.warn ("Exception encountered during context initialization-cancelling refresh attempt:" + var10);} / / destroy the generated bean this.destroyBeans () if an exception occurs; / / reset the refresh field information this.cancelRefresh (var10) Throw var10;} finally {/ / initialize some cache information this.resetCommonCaches (); contextRefresh.end ();}

Viewing bean Definitions and registrations from a SpringBoot Perspective

1. Automatically load configuration classes

2. Bean definition and registration

Note: springboot only has more automatic configuration related processes than spring and has done a layer of logical encapsulation on spring.

Instantiation, dependency injection, initialization

AbstractAutowireCapableBeanFactory is an implementation class of the AutowireCapableBeanFactory interface, where a method doCreateBean () of the AbstractAutowireCapableBeanFactory implementation class

Location: AbstractAutowireCapableBeanFactory#doCreateBeanprotected Object doCreateBean (String beanName, RootBeanDefinition mbd, @ Nullable Object [] args) throws BeanCreationException {BeanWrapper instanceWrapper = null; if (mbd.isSingleton ()) {instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove (beanName);} if (instanceWrapper = = null) {/ / instantiation phase instanceWrapper = this.createBeanInstance (beanName, mbd, args);}. Object exposedObject = bean; try {/ / dependency injection, attribute assignment phase this.populateBean (beanName, mbd, instanceWrapper); / / initialization phase exposedObject = this.initializeBean (beanName, exposedObject, mbd);} catch (Throwable var18) {.}.}

As you can see, three methods are called:

CreateBeanInstance ()-> instantiation

PopulateBean ()-> dependency injection

InitializeBean ()-> initialize

Destroy

The destroy phase is called when the container is closed, in ConfigurableApplicationContext#close ()

As for classes such as xxxAware,BeanPostProcessor,BeanFactoryPostProcessor, they are just a series of extension points to the main process.

Extension points for the lifecycle of Bean

There are many extension points in the life cycle of Spring Bean, and it is impossible to list them all here, just the core extension points. This is why Spring has good scalability, opening a lot of openings to make a function as cohesive and loosely coupled as possible, and users can use whatever function they need, instead of directly coming to a big and comprehensive thing.

Bean level

The implementation classes of these interfaces are based on Bean, and the Bean that implements these interfaces only works.

BeanNameAware

BeanFactoryAware

ApplicationContextAware

InitializingBean

DisposableBean

There are also a lot of xxxAware, which are not commonly used, and the following lifecycle tests are not added, such as:

BeanClassLoaderAware

EnvironmentAware

EmbeddedValueResolverAware

ResourceLoaderAware

ApplicationEventPublisherAware

MessageSourceAware

ServletContextAware

Container level

The implementation classes for these interfaces are independent of Bean and are registered in the Spring container. Their implementation classes are generally called post processors.

These post processors work when the Spring container creates any Bean

BeanPostProcessor

InstantiationAwareBeanPostProcessor (InstantiationAwareBeanPostProcessor inherits BeanPostProcessor)

The factory post-processor interface is also container-level. Called immediately after applying the contextual assembly configuration file:

AspectJWeavingEnabler

ConfigurationClassPostProcessor

CustomAutowireConfigurer

Common interface InstantiationAwareBeanPostProcessor

This class is a subinterface of BeanPostProcessor, and there are three common methods:

PostProcessBeforeInstantiation (Class beanClass, String beanName): called before bean instantiation

PostProcessProperties (PropertyValues pvs, Object bean, String beanName): called after bean instantiation and before setting properties

PostProcessAfterInstantiation (Class beanClass, String beanName): called after bean instantiation

BeanNameAware

The BeanNameAware interface is designed to make its own Bean aware that there is only one method, setBeanName (String name), to get its own id or name property in the Spring container.

BeanFactoryAware

This interface has only one method setBeanFactory (BeanFactory beanFactory), which is used to get the BeanFactory in the current environment and can be extended to all bean in the factory.

ApplicationContextAware

This interface has only one method, setApplicationContext (ApplicationContext applicationContext), which is used to get the ApplicationContext in the current environment and can be extended to the entire container.

Note: sometimes this API is not called, which depends on your IOC container: the minimum requirement of a Spring IOC container is to implement the BeanFactory interface, not the ApplicationContext interface. For those containers that do not implement the ApplicationContext interface, the methods defined by the ApplicationContextAware corresponding to the lifecycle will not be called. Only the container that implements the ApplicationContext interface will be called.

BeanPostProcessor

PostProcessBeforeInitialization (Object bean, String beanName): this method is called before initialization, which is used by Spring's AOP.

PostProcessAfterInitialization (Object bean, String beanName): call this method after initialization

InitializingBean

The interface has only one method, afterPropertiesSet (), which is called after the property injection is complete.

All classes that inherit this interface will execute this method when initializing bean, and you can do some work such as property configuration.

InitializingBean corresponds to the initialization phase of the life cycle and is called in the invokeInitMethods (beanName, wrappedBean, mbd) method of the source code.

DisposableBean

The function of this API is to call when the object is destroyed, and you can do some resource destruction operations.

DisposableBean is similar to InitializingBean, corresponding to the destruction phase of the life cycle, with the ConfigurableApplicationContext#close () method as the entry. The implementation is to loop through all the Bean that implements the DisposableBean interface and then call its destroy () method.

Common annotations @ Bean (initMethod = "initMethod", destroyMethod = "destroyMethod")

@ Bean declares a bean for use with @ Configuration annotations

InitMethod: call back a method when declaring bean initialization, which needs to be written by a programmer

DestroyMethod: call back a method when declaring bean destruction, which requires programmers to write

@ PostConstruct

An Annotation-based initialization method for bean

@ PreDestroy

An Annotation-based destruction method for bean

The case study declares a bean@Configurationpublic class BeanInitAndDestroyConfig {/ * @ return where no bean name is specified. The default is the method name * / @ Description ("testing the life cycle of bean") @ Bean (initMethod = "initMethod", destroyMethod = "destroyMethod") public MyService myServiceBeanName () {/ / input parameter to inject other dependencies return new MyService ();}}

Declare a bean named myServiceBeanName

The initialization method of initMethod:bean is: initMethod

The destruction method of destroyMethod:bean is: destroyMethod

Animal implementation class

This is just to show that the @ Qualifier annotation can match according to the bean name.

My service class

That is, an interface that is called only once for the current bean

/ * * @ Description: bean life cycle test: these APIs are only for the current bean * @ Author: jianweil * @ date: 9:46 * / public class MyService implements Person on 2021-12-8, BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {private Animal animal = null; private ApplicationContext applicationContext; / * API specification method * / @ Override public void service () {this.animal.use () } public MyService () {System.out.println ("2. [bean instantiation]:" + this.getClass () .getSimpleName () + "- Construction method") } / * * API specifies the method: injection dependency * / @ Override @ Autowired @ Qualifier ("dog") public void setAnimal (Animal animal) {System.out.println ("5. [bean attribute assignment]: dog---- dependency injection"); this.animal = animal;} @ Override public void setBeanName (String s) {System.out.println ("6. Call [BeanNameAware]-- setBeanName: "+ s);} @ Override public void setBeanFactory (BeanFactory beanFactory) throws BeansException {System.out.println (" 7. Call [BeanFactoryAware]-- setBeanFactory ");} @ Override public void setApplicationContext (ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext; System.out.println (" 8. Call [ApplicationContextAware]-- setApplicationContext "); initialize 1 * / @ PostConstruct public void myInit () {System.out.println (" 10. [initialization] Note @ PostConstruct custom initialization method [myInit] ");} / * * initialization 2 * / @ Override public void afterPropertiesSet () throws Exception {System.out.println (" 11. [initialize] API InitializingBean method [afterPropertiesSet] ");} / * * initialize 3 * / public void initMethod () {System.out.println (" 12. [initialization] Note @ Bean custom initialization method [initMethod] ");} / * * destroy 1 * / @ PreDestroy public void myDestroy () {System.out.println (" 14. [destroy] Note @ PreDestroy Custom termination method [myDestroy] ");} / * * destroy 2 * / @ Override public void destroy () throws Exception {System.out.println (" 15. [destroy] API DisposableBean method [destroy] ");} / * * destroy 3 * / public void destroyMethod () {System.out.println (" 16. [destroy] Note @ Bean Custom termination method [destroyMethod] ");}}

The interface implemented here only works on the current bean (that is, the bean named myDefineBeanName defined above by @ bean)

Post processor

Execute once per bean lifecycle

The post processor is the life cycle that acts on all bean in the ioc container.

/ * @ Description: todo * @ Author: jianweil * @ date: 17:20 * / @ Componentpublic class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {@ Override public Object postProcessBeforeInstantiation (Class beanClass, String beanName) throws BeansException {if ("myServiceBeanName" .equals (beanName) | | "dog" .equals (beanName)) {System.out.println ("= = InstantiationAwareBeanPostProcessor- start ="); System.out.println ("1. [callback every bean at container level] call the InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation () method: beanName is "+ beanName);} return null;} @ Override public boolean postProcessAfterInstantiation (Object bean, String beanName) throws BeansException {if (" myServiceBeanName ".equals (beanName) | |" dog ".equals (beanName)) {System.out.println (" 3. Call the InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation () method: beanName is "+ beanName);} return true;} @ Override public PropertyValues postProcessProperties (PropertyValues pvs, Object bean, String beanName) throws BeansException {if (" myServiceBeanName ".equals (beanName) | |" dog ".equals (beanName)) {System.out.println (" 4. [callback every bean at container level] call the InstantiationAwareBeanPostProcessor.postProcessProperties () method: beanName is "+ beanName); System.out.println (" = = InstantiationAwareBeanPostProcessor- end = = ");} return null }} / * * @ Description: initializer of the post-bean: all bean will intercept the execution of * @ Author: jianweil * @ date: 9:46 on 2021-12-8 * / @ Componentpublic class MyBeanPostProcessor implements BeanPostProcessor {@ Override public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException {/ / here filter out the bean automatically configured by springboot Only print the bean of our project if ("myServiceBeanName" .equals (beanName) | | "dog" .equals (beanName)) {System.out.println ("9. [callback every bean at container level] call the BeanPostProcessor.postProcessBeforeInitialization method: beanName is "+ beanName);} return bean;} @ Override public Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException {if (" myServiceBeanName ".equals (beanName) | |" dog ".equals (beanName)) {System.out.println (" 13. [callback every bean at container level] call the BeanPostProcessor.postProcessAfterInitialization method: beanName is "+ beanName);} return bean;}} factory post processor

Container level, only allowed once

@ Componentpublic class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@ Override public void postProcessBeanFactory (ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println ("0. [container level is called only once] call BeanFactoryPostProcessor.postProcessBeanFactory () method");} output result and result interpretation

"/" marked for interpretation

/ / the factory post processor at the container level calls 0. 0 only once after applying the context assembly configuration file. [call container level only once] call the BeanFactoryPostProcessor.postProcessBeanFactory () method / / because our life process only prints ("myServiceBeanName" .equals (beanName) | | "dog" .equals (beanName)). Only constructors for all cats print cat-constructor / / # # dog lifecycle # # / / postprocessor, container level Action on all bean==InstantiationAwareBeanPostProcessor- starts = = 1. [callback every bean at container level] call the InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation () method: beanName is the instantiated dog of dog// dog-constructor / / postprocessor, container level, acting on all bean3. [callback every bean at container level] call the InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation () method: beanName is the dog// post processor, container level, and works on all bean4. [callback every bean at container level] call the InstantiationAwareBeanPostProcessor.postProcessProperties () method: beanName ends with dog==InstantiationAwareBeanPostProcessor- = = / / postprocessor, container level, acting on all bean9. [callback every bean at container level] call the BeanPostProcessor.postProcessBeforeInitialization method: beanName is the post-processor of dog//, container level, and works on all bean13. [callback every bean at container level] call the BeanPostProcessor.postProcessAfterInitialization method: beanName is bean completion of dog//##dog, start myServiceBeanName###// post processor, container level Action on all bean==InstantiationAwareBeanPostProcessor- starts = = 1. [callback every bean at container level] call the InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation () method: beanName instantiates myServiceBeanName// 2. [bean instantiation]: MyService- constructor method / / post processor, container level, acting on all bean3. [callback every bean at container level] call the InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation () method: beanName is the myServiceBeanName// post processor, container level, and works on all bean4. [callback every bean at container level] call the InstantiationAwareBeanPostProcessor.postProcessProperties () method: beanName ends the myServiceBeanName==InstantiationAwareBeanPostProcessor- assignment of = / / attribute, that is, dependency injection 5. [bean attribute assignment]: dog---- dependency injection / / bean level, and bean:myServiceBeanName implements the interface BeanNameAware6. Call [BeanNameAware]-- setBeanName:myServiceBeanName//bean level 7. Call [BeanFactoryAware]-- setBeanFactory//bean level 8. Call [ApplicationContextAware]-- setApplicationContext// post processor, container level, works on all bean: pre-initialization processing 9. [callback every bean at container level] call the BeanPostProcessor.postProcessBeforeInitialization method: beanName initializes 10. 0 for myServiceBeanName//. [initialization] Note @ PostConstruct Custom initialization method [myInit] 11. [initialization] API InitializingBean method [afterPropertiesSet] 12. [initialization] Note @ Bean Custom initialization method [initMethod] / / Post processor, container level, works on all bean: post-initialization processing 13. [callback every bean at container level] call the BeanPostProcessor.postProcessAfterInitialization method: when beanName loads the myServiceBeanName// container environment, you can use all bean2021-12-21 11 18-bean2021-[main] c.l.s.SpringbootBeanLifecycleApplication: Started SpringbootBeanLifecycleApplication in 0.719 seconds (JVM running for 1.312) / / destroy 14. [destroy] Note @ PreDestroy Custom termination method [myDestroy] 15. [destroy] API DisposableBean method [destroy] 16. [destroy] Note @ Bean Custom termination method [destroyMethod] Process finished with exit code 0Bean Lifecycle Chart

The point of understanding the Spring lifecycle is that you can use Bean to do something at a specified time during its lifetime. In general, some actions are performed after the Bean is initialized and before it is destroyed.

The above is how to gain an in-depth understanding of Spring's Bean life cycle. Have you learned any knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report