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 specify several poses of initialization order in SpringBoot Bean

2025-04-06 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

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

SpringBoot Bean how to specify the initialization order of a number of postures, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain in detail for you, people with this need can come to learn, I hope you can gain something.

i. Environment building

Our test project and the previous blog post share a project environment, of course, you can also build a new test project, the corresponding configuration is as follows: (source address at the end of the article)

Org.springframework.boot spring-boot-starter-parent 2.1.7 UTF-8 UTF-8 Finchley.RELEASE 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-maven-plugin spring-milestones Spring Milestones https://repo.spring.io/milestone false II. The initialization order specifies 1. Construction method dependence

This can be said to be the simplest and most common posture, but when using it, we need to pay attention to problems such as circular dependency.

We know that one of the ways to inject bean is through the construction method, and in this way, we can solve the initialization order between bean with priority requirements.

For example, if we create two Bean and require the CDemo2 to be initialized before the CDemo1, then our available way

@ Componentpublic class CDemo1 {private String name = "cdemo 1"; public CDemo1 (CDemo2 cDemo2) {System.out.println (name);}} @ Componentpublic class CDemo2 {private String name = "cdemo 1"; public CDemo2 () {System.out.println (name);}}

The measured output results are as follows, which is consistent with our expectations.

Although this approach is straightforward and simple, there are several limitations.

An injection relationship is required, for example, CDemo2 is injected into a CDemo1 through construction. It is not appropriate to specify a priority between two bean that do not have an injection relationship (for example, I want a bean to be executed before all other Bean initialization).

Circular dependency problem. If the above CDemo2 constructor has a CDemo1 parameter, then the circular dependency is generated and the application cannot be started.

Another point to note is that in the construction method, there should be no complex and time-consuming logic, which will slow down the startup time of the application.

2. @ DependOn comment

This is a dedicated solution to the dependency problem of bean, which can be used when a bean needs to be initialized after another bean is initialized.

The way to use it is also relatively simple. Here is a simple example, case.

@ DependsOn ("rightDemo2") @ Componentpublic class RightDemo1 {private String name = "right demo 1"; public RightDemo1 () {System.out.println (name);}} @ Componentpublic class RightDemo2 {private String name = "right demo 2"; public RightDemo2 () {System.out.println (name);}}

The above note is placed on RightDemo1, indicating that the initialization of RightDemo1 depends on rightDemo2, the bean

It is important to note that when using this annotation, it can control the instantiation order of bean, but the order of bean initialization operations (such as calling the initialization method of @ PostConstruct annotation after constructing a bean instance) is not guaranteed. For example, our following example illustrates this problem.

@ DependsOn ("rightDemo2") @ Componentpublic class RightDemo1 {private String name = "right demo 1"; @ Autowired private RightDemo2 rightDemo2; public RightDemo1 () {System.out.println (name);} @ PostConstruct public void init () {System.out.println (name + "_ init");}} @ Componentpublic class RightDemo2 {private String name = "right demo 2"; @ Autowired private RightDemo1 rightDemo1 Public RightDemo2 () {System.out.println (name);} @ PostConstruct public void init () {System.out.println (name + "_ init");}}

Note that although there is a circular dependency in the above code, it is injected through the @ Autowired annotation, so it will not cause the application to fail to start. Let's take a look at the output first.

The interesting thing is that we use the @ DependsOn annotation to make sure that before we can create a RightDemo1, we have to create a RightDemo2

So as you can see from the output of the constructor, first instance RightDemo2, then instance RightDemo1

As you can see from the output of the initialization method, in the above scenario, although the RightDemo2 bean is created, its initialization code is executed later.

Beside the question: interested students can try to delete the dependency injection of @ Autowired in the above test code, that is, the two bean do not inject dependencies into each other, and when they execute again, they will find that the output order is not the same.

3. BeanPostProcessor

Finally, an atypical use is introduced. If it is not necessary, please do not use this way to control the loading order of bean.

First create two test bean

@ Componentpublic class HDemo1 {private String name = "h demo 1"; public HDemo1 () {System.out.println (name);}} @ Componentpublic class HDemo2 {private String name = "h demo 2"; public HDemo2 () {System.out.println (name);}}

We want HDemo2 to be loaded before HDemo1, and with BeanPostProcessor, we can do this in the following way

@ Componentpublic class DemoBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements BeanFactoryAware {private ConfigurableListableBeanFactory beanFactory; @ Override public void setBeanFactory (BeanFactory beanFactory) {if (! (beanFactory instanceof ConfigurableListableBeanFactory)) {throw new IllegalArgumentException ("AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory:" + beanFactory);} this.beanFactory = (ConfigurableListableBeanFactory) beanFactory } @ Override @ Nullable public Object postProcessBeforeInstantiation (Class beanClass, String beanName) throws BeansException {/ / do something before bean instantiation if ("HDemo1" .equals (beanName)) {HDemo2 demo2 = beanFactory.getBean (HDemo2.class);} return null;}}

Please focus on postProcessBeforeInstantiation, which is called before a bean is instantiated, which gives us a chance to control the loading order of the bean.

See this kind of coquettish operation, is not a bit ready to move, for example, I have a bean, I hope that after the application is started, other bean will be loaded before instantiation, is it possible to do so in this way?

Here is a simple example, demo, which overrides the postProcessAfterInstantiation method of DemoBeanPostProcessor. After the application is created, our FDemo bean is loaded.

@ Overridepublic boolean postProcessAfterInstantiation (Object bean, String beanName) throws BeansException {if ("application" .equals (beanName)) {beanFactory.getBean (FDemo.class);} return true;} @ DependsOn ("HDemo") @ Componentpublic class FDemo {private String name = "F demo"; public FDemo () {System.out.println (name);} @ Componentpublic class HDemo {private String name = "H demo" Public HDemo () {System.out.println (name);}}

As you can see from the output of the following figure, the instantiation order of HDemo and FDemo is at the top.

4. Summary

Before summarizing, it is pointed out that a complete bean creation distinguishes the order of the two blocks in this article.

Instantiate (call constructor)

Initialization (injecting dependency properties, calling the @ PostConstruct method)

This paper mainly introduces three ways to control the loading order of bean.

The initialization order between dependent bean can be controlled by the way of constructor dependency, but we need to pay attention to the problem of circular dependency.

@ DependsOn annotation to control the order of instances between bean. It should be noted that the order of initialization method calls of bean cannot be guaranteed.

BeanPostProcessor mode to manually control the loading order of bean

Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.

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

Internet Technology

Wechat

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

12
Report