Three ways to solve circular dependency in spring

Introduction: circular dependency is a circular nested reference in n classes. If this circular dependency occurs in the way of new objects in daily development, the program will call circularly until an error is reported due to memory overflow. Let's talk about how spring solves circular dependency.

First: constructor parameter circular dependency

Indicates a circular dependency formed by constructor injection. This dependency cannot be solved. Only beancurrentlyin creationexception exception can be thrown to indicate a circular dependency.

If the constructor needs testb class when creating testa class, it will create testb. If it finds that testc class is needed when creating testb class, it will create testc again. Finally, it finds that testa is needed when creating testc, thus forming a ring. There is no way to create it.

The spring container will place each bean identifier being created in a "currently created bean pool", and the bean identifier will always remain in this pool during the creation process. Therefore, if you find yourself in the "currently created bean pool" during the creation process, you will throw a beancurrentyincreationexception exception, indicating circular dependency; The created bean will be cleared from the "currently created bean pool".

First, we initialize three beans.

OK, there are three basic classes above. The parameter structure of studenta is Studentb. The parameterized construction of Studentb is studentc, and the parameterized construction of studentc is studenta, resulting in a circular dependency. We all hand over the three beans to spring for management and instantiate them with the parameterized construction

The following are test classes:

The error message of the execution result is:

Caused by: org. springframework. beans. factory. BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?

If you understand the first sentence, you should not be surprised by this error. The spring container first creates a singleton studenta, which depends on Studentb, and then puts a in the "currently created bean pool". At this time, Studentb is created, Studentb depends on studentc, and then puts B in the "currently created bean pool". At this time, studentc is created, and studentc depends on studenta. However, At this time, the student is already in the pool, so an error will be reported. Because the beans in the pool are uninitialized, they will rely on an error (the initialized beans will be removed from the pool)

The second method: setter mode, single example, default mode

If we want to talk about setter injection, we'd better look at a diagram of bean instantiation in spring

As shown in the first two steps in the figure, spring instantiates the bean object before setting the object properties

Modify the configuration file to set injection

The following are test classes:

The print result is:

com. zfx. student. StudentA@1fbfd6

Why don't you report an error by using set?

In combination with the above figure, spring instantiates bean objects with constructs. At this time, spring will put the instantiated object into a map, and spring provides a method to obtain the instantiated object reference without setting properties. From our example, when spring instantiates studenta, Studentb and studentc, it will set the properties of the object. At this time, studenta depends on Studentb, and it will take out the single instance Studentb object in the map, and so on. There will be no looping problem

The following is the implementation method in the spring source code,. The following source code is in the defaultsingletonbeanregistry in the bean package of spring Java class

The third: setter mode prototype, prototype

For "prototype" scope beans, the spring container cannot complete dependency injection because the spring container does not cache "prototype" scope beans, so it cannot expose a bean under creation in advance.

Modify the configuration file as:

Scope = "prototype" means that an instance object will be created for each request. The difference between the two is that stateful beans use prototype scope, while stateless beans generally use singleton singleton scope.

Test case:

Print results:

Caused by: org. springframework. beans. factory. BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?

Why is the prototype model wrong?

For "prototype" scoped beans, the spring container cannot complete dependency injection, because the spring container does not cache the "prototype" scoped beans, so it cannot expose a bean under creation in advance.

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>