CodeGym /Java Course /Module 5. Spring /Dependency resolution process

Dependency resolution process

Module 5. Spring
Level 3 , Lesson 5
Available

The container resolves bean dependencies as follows:

  • The ApplicationContext is created and initialized using configuration metadata that describes all beans. Configuration metadata can be specified using XML, Java code, or annotations.

  • For each bean, its dependencies are expressed as properties, constructor arguments, or static factory method arguments (if you use one instead of a regular constructor). These dependencies are provided to the bean when it is actually created.

  • Each property or constructor argument represents an actual definition of a value to be set, or a reference to another bean in the container.

  • Each property or constructor argument that is a value is converted from the specified format to the actual type of that property or constructor argument. By default, Spring can convert a value provided in string format to all built-in types such as int, long, String, boolean and so on.

The Spring container checks the configuration of each bean when the container is created. However, the bean properties themselves are not set until the bean is created. Beans that are scoped to singleton and are configured to be pre-instantiated (the default) are created when the container is created. Otherwise, the bean is created only when a request is received. Creating a bean potentially creates a bean dependency graph, as the bean's dependencies, the dependencies of its dependencies (and so on) are created and assigned. Note that inconsistencies in the resolution of these dependencies may become apparent late, that is, when the affected bean is first created.

Cyclic dependencies

If you primarily use constructor injection, you can create an intractable circular dependency scenario.

For example: Class A requires an instance of class B through constructor-based injection, and class B requires an instance of class A through constructor-based injection. If you configure beans of classes A and B to inject each other, the Spring IoC container will detect this circular reference at runtime and throw a BeanCurrentlyInCreationException.

One possible solution is to edit the source code of some classes so that configuration is done using setters rather than constructors. Alternatively, avoid constructor dependency injection and use setter injection exclusively. In other words, although not recommended, it is possible to set up circular dependencies using setter injection.

Unlike the typical case (without circular dependencies), a circular dependency between bean A and bean B causes one of the beans to be injected into the other before it is itself fully initialized (a classic chicken and egg scenario (cause and effect)").

You can generally trust Spring to do everything right. It detects configuration problems, such as references to non-existent beans and circular dependencies, while the container is loading. Spring sets properties and resolves dependencies as late as possible, after the bean has already been created. This means that a Spring container that has loaded correctly may later throw an exception when requesting an object if there is a problem creating that object or one of its dependencies - for example, a bean throws an exception as a result of a missing or invalid property. This potentially delayed visibility of some configuration issues is why ApplicationContext implementations pre-instantiate singleton beans by default. By spending some time and memory creating these beans before you actually need them, you'll find configuration problems when you create the ApplicationContext rather than later. You can still override this default behavior so that singleton beans are initialized lazily instead of pre-instantiating them as quickly as possible.

If circular dependencies do not exist, then when one or more interacting beans are injected into a dependent bean, each interacting bean is fully configured before being injected into the dependent bean. This means that if bean A depends on bean B, the Spring IoC container fully configures bean B before calling the setter on bean A. In other words, the bean is instantiated (unless it is a pre-created singleton), its dependencies are installed, and the corresponding ones are called Lifecycle methods (such as the configured init method or the InitializingBean callback method).

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION