Spring loop dependence

1. Background

Add an asynchronous processing function (@asyc) to the sorting service. During local testing, it was found that the service was sometimes normal and sometimes abnormal after starting the service.

Problem analysis

1. In the same environment, the results of starting the service are different. It is positioned as the engineering code that caused the exception.

2. In the startup class, wildcards are used in the configuration file name. Theoretically, the configuration file loading sequence is not fixed.

3. It can be seen from the log on the machine that the spring/application-xxx.xml loading sequence is different when the startup is successful and when it is abnormal.

4. Two problems can be seen from the error log: circular dependency and different beans depend on different versions of the same bean. (Spring supports circular dependencies by default)

Description:

1. Bean instantiation process: create bean → cache bean → inject element → inject element → inject element … …→ finish (debug mode can track the complete bean instantiation process)

2, acyclic dependency scenario

Condition: A depends on B, if first create A

The instantiation process is: create A → cache A → create B → cache B → finish B → inject B to A → finish A. (The dependent object is finished first, that is, B is instantiated before A)

3. Cyclic dependency scenario

Condition: A depends on B, B depends on A, if you create A first< /p>

The instantiation process is: create A → cache A → create B → cache B → inject A to B → finish B → inject B to A → finish A. (Spring allows eagerly cached instance to be injected into other beans, eagerly cached instance refers to the cached but not finished bean)

The dependency of the bean in the clearing project is more complicated, abstract The following scenario is explained: (The following beans are all in singleton mode. In non-singleton mode, beans will not be cached and do not support circular dependencies)

Step 1: A depends on B, C depends on B, B depends on C, and there is an @async annotation on the method of B’s ​​implementation class, that is, B will generate a proxy before the instantiation is completed.
Step 2: A starts create, and finds that B has not been instantiated, so first cache A.
Step 3: B starts create, and finds that C is not instantiated, so cache B first.
Step 4: C starts create, finds that B has been instantiated, takes out B from the cache, injects it into C, and finishes C.
(Why is B injected into C without instantiating it? That is not fully initialized yet-a consequence of a circular reference, because there is a circular dependency, so it is allowed to inject first. Guess whether it is detected by the proxy is not done)
Step 5: Generate B’s proxy class [email protected].
Step 6: When [email protected] is injected into A, it is found that the original instance B of [email protected] has been injected into the circular reference C, but the final proxy class [email protected] of B is not used, so an exception is thrown.

The normal situation should be that B finishes first, and A and C finish later, so that the final proxy class of B can be injected into A and C.

Beware of traps

1. The depends-on setting: If A depends-on B, it will only ensure that B is instantiated before A (Creating instance of bean), but there is no guarantee that B is completed before A instance (Finished creating instance of bean). For simple beans, the order of completion of instantiation is normal.

2, try to keep the bean dependency simple.

3. Ensure that the bean loading sequence is fixed.

4. When injecting service, try to inject mapper as much as possible. Otherwise, after multiple iterations of business changes, circular dependencies will be easily exposed. ———————————————— Copyright statement: This article is the original article of the CSDN blogger “white background and black text”. It follows the CC 4.0 BY-SA copyright agreement. Please attach the original source link for reprinting. And this statement. Original link: https://blog.csdn.net/lianhuazy167/article/details/66967673

Leave a Comment

Your email address will not be published.