SoFunction
Updated on 2025-04-07

Detailed explanation of Spring's core mechanism dependency injection

Detailed explanation of Spring's core mechanism dependency injection

For general Java projects, they all have a more or less dependency relationship, that is, they are composed of some collaborative objects. Spring calls this collaborative relationship a dependency relationship. For example, if component A calls component B, component A can be said to depend on component B. Dependency injection allows Spring's Beans to be organized together in configuration files, rather than being coupled together in a hard-coded manner.

1. Understand dependency injection

Dependency Injection = Inversion of Control (IoC): When a Java instance (caller) requires another Java instance (caller), in dependency injection mode, the work of creating the callee is no longer completed by the caller, so it is called control inversion; the work of creating the callee instance is usually done by the Spring container and then injected into the caller, so it is also called dependency injection

Dependency injection: When another object needs to cooperate (calling its methods and accessing its properties) during the program, it does not need to create the callee in the code, but depends on the injection of external containers. Spring's dependency injection has almost no requirements for the caller and the callee, and fully supports the management of dependencies between POJOs.

Dependency injection

Set value injection: IoC container uses the setter method of attributes to inject the dependent instance

Construct Injection: IoC containers use constructors to inject depended instances

Understand dependency injection:

A person (Java instance, caller) needs an axe (Java instance, caller)

In primitive society, there was almost no social division of labor; people who needed an axe (caller) could only polish an axe (caller); the corresponding situation was: the caller in a Java program created the caller by himself, and usually used the new keyword to call the constructor to create a caller.

Entering the industrial society, factories appear, and axes are no longer completed by ordinary people, but are produced in factories. At this time, people who need axes (callers) find the factory and buy the axes without caring about the manufacturing process of the axes; corresponding to the simple factory design model, the caller only needs to locate the factory and does not need to manage the specific implementation of the callee.

Entering the "*" society, those who need axe do not even need to locate the factory or wait for the "sitting" society to provide it; the caller does not need to care about the implementation of the callee, does not need to pay attention to the factory, and wait for Spring dependency injection.

2. Set value injection

Personinterface: 
public interface Person { 
  // Define the method of using axe  public void useAxe(); 
} 
Spring推荐面向interface编程,This can better separate specifications and achieve,This provides better decoupling;For aJava EEapplication,No matter whatDAOComponent or business logic component,都应该先定义一个interface,该interface定义了该组件应实现的功能,However, the implementation of the function is provided by its implementation class 
Axeinterface: 
public interface Axe { 
  // There is a method to cut in the Axe interface  public String chop(); 
} 
accomplishAxe: 
public class StoneAxe implements Axe { 
  public String chop() { 
    return "Stone axe chops wood very slowly"; 
  } 
} 

: 

<?xml version="1.0" encoding="UTF-8"?> 
<!-- SpringThe root element of the configuration file,usespring-beans-3.Semantic constraints --> 
<beans xmlns:xsi="http:///2001/XMLSchema-instance" 
 xmlns="/schema/beans" 
 xsi:schemaLocation="/schema/beans 
 /schema/beans/spring-beans-3."> 
  
 <!-- ConfigurationchineseExample --> 
 <bean  class=""> 
   <!-- WillstoneAxeInject toaxeproperty --> 
   <property name="axe" ref="stoneAxe" /> 
 </bean> 
  
 <!-- ConfigurationstoneAxeExample --> 
 <bean  class="" /> 
  
</beans> 

Test class:

public class BeanTest { 
  public static void main(String[] args) { 
   // Create Spring Container   ApplicationContext ctx = new ClassPathXmlApplicationContext(""); 
   // Get chinese instance   Person p = ("chinese", ); 
   // Call the useAxe() method   (); 
  } 
} 

Spring uses XML as a configuration file. Starting from Spring 2.0, Spring can use DTD to define the semantic constraints of the configuration file, and can also be defined by XML Schema (the expansion of Spring configuration files can be used to further simplify Spring configuration; some new tags are also provided; programmers are also allowed to develop customized configuration file tags, allowing other developers to use these tags in Spring configuration files: usually done by third-party vendors);

Various *.xsd files (XML Schema semantic constraint files for Spring configuration files) can be found in the \src\main\resources path of Spring projects directory, etc. directory.

In a configuration file, Spring configuration bean instances usually specify:

id: Specify the unique identifier of the bean. The program accesses the bean instance through the id attribute value.

class: Specifies the implementation class of the bean. Interfaces are no longer available here. The implementation class Spring container must use the XML parser to read the property, and use reflection to create an instance of the implementation class

Spring will automatically take over the <property.../> element definition in each <bean.../> definition. Spring will inject property values ​​into the program after calling the parameterless constructor, create the default bean instance, and call the corresponding setter method.

The id attribute of each bean is the unique identifier of the bean. The program accesses the bean through the id attribute. The dependency between the bean and the bean is also associated with the id attribute.

The dependency between beans and beans is managed by Spring. Spring uses the setter method to inject the dependency beans into the target beans. This method is called set value injection

3 basic points of using Spring IoC containers:

The various components of the application are interface-oriented programming

The components of the application are no longer actively generated by the program, but are generated and initialized by the Spring container.

Spring uses configuration files or Annotation to manage the implementation classes and dependencies of beans. Spring containers create instances based on configuration files and use reflections and inject dependencies into them.

3. Structural injection

When constructing an instance, the initialization of the dependency has been completed for it. This way of using constructors to set dependencies is called construct injection

public class Chinese implements Person { 
 private Axe axe; 
  
 // Default constructor public Chinese() { 
 } 
  
 // Construct the constructor with parameters required for injection public Chinese(Axe axe) { 
    = axe; 
 } 
  
 // Implement the useAxe method of Person interface @Override 
 public void useAxe() { 
   // Call axe's chop() method   // Indicates that Person object depends on axe object   (()); 
 } 
} 

There is no need to provide a setter method to set the axe attribute. It only provides a constructor with the Axe attribute. Spring will inject the dependable bean instance into chinese through this constructor.

&lt;?xml version="1.0" encoding="UTF-8"?&gt; 
&lt;!-- SpringThe root element of the configuration file,usespring-beans-3.Semantic constraints --&gt; 
&lt;beans xmlns:xsi="http:///2001/XMLSchema-instance" 
 xmlns="/schema/beans" 
 xsi:schemaLocation="/schema/beans 
 /schema/beans/spring-beans-3."&gt; 
  
 &lt;!-- ConfigurationchineseExample --&gt; 
 &lt;bean  class=""&gt; 
   &lt;!-- use构造注入,forchineseExample注入stoneAxeExample --&gt; 
   &lt;constructor-arg ref="stoneAxe" /&gt; 
 &lt;/bean&gt; 
  
 &lt;!-- ConfigurationstoneAxeExample --&gt; 
 &lt;bean  class="" /&gt; 
  
&lt;/beans&gt; 

The <constructor-arg.../> element specifies a constructor parameter, which is Axe, which specifies that Spring calls the constructor with an Axe parameter in the Chinese class to create a chinese instance. Because the constructor with parameters is used to create an instance, when the bean instance is created, the dependency of the bean has been set after the bean instance is created, the bean's dependency has been set.

When configuring the <constructor-arg.../> element, you can specify an index attribute to specify which constructor parameter value will be used as the first constructor parameter value; if index = "0" indicates that the constructor parameter value will be used as the first constructor parameter

The execution effect is exactly the same as when using settings injection. The difference is that the time to create the Axe attribute in the Person instance is different - setting the injection is to first create a Bean instance through a constructor without parameters, and then call the corresponding setter method to inject the dependency; while construct injection directly calls the constructor with parameters. When the bean instance is created, the dependency injection has been completed.

4. Comparison of two injection methods

In contrast, the set value injection has the following advantages:

It is more similar to the traditional JavaBean writing method, and it is easier for program developers to understand, accept, and set dependencies through setter methods to make it more intuitive and natural.

For complex dependencies, if construct injection is used, the constructor will be too bloated and difficult to read; when Spring creates a bean instance, it needs to instantiate all instances of its dependencies at the same time, resulting in performance degradation

Especially when certain attributes are optional, multi-parameter constructors are more bulky

In contrast, construction injection has the following advantages:

The order of injection of dependencies can be determined in the constructor, and the priority injection of priority dependencies can be determined.

For beans where dependencies do not need to be changed, construct injection is more useful; because there is no setter method, all dependencies are set in the constructor. Therefore, there is no need to worry about subsequent code breaking the dependency

The dependency can only be set in the constructor, so only the creator of the component can change the dependency of the component. For component callers, the dependencies within the component are completely transparent and more in line with the principle of high cohesion.

Generally, an injection strategy based on set value injection is adopted, and a structure injection is supplemented. For injections that do not require changes in dependencies, try to use construct injection; for injections of other dependencies, set value injection is considered.

If you have any questions, please leave a message or go to the community of this site to exchange and discuss. Thank you for reading. I hope it can help you. Thank you for your support for this site!