Introduce Spring's core mechanism dependency injection and spring's Core Mechanism
Introduce Spring's core mechanism dependency Injection
For general Java projects, they all have a more or less dependent relationship, that is, they are composed of some mutual collaboration objects. Spring calls this cooperative relationship dependency. For example, if component A calls the method of component B, component A depends on Component B. Dependency injection means that Spring beans are organized together by configuration files, rather than being coupled together in hard coding.
1. Understand dependency Injection
Dependency Injection = Inversion ofControl (IoC): When a Java instance (caller) needs another Java instance (called), in the Dependency Injection mode, the creation of the called instance is no longer completed by the caller. Therefore, it is called control inversion. The creation of the called instance is usually completed by the Spring container and then injected into the caller. Therefore, it is also called dependency injection.
Dependency injection: when a program is running, if you need to collaborate with another object (call its method and access its attributes), you do not need to create the called user in the code, it depends on the injection of external containers. Spring dependency injection has almost no requirements on callers and callers. It fully supports the management of dependencies between POJO.
Dependency Injection
Set Value injection: The IoC container uses the setter method of the attribute to inject the dependent instance.
Constructor injection: The IoC container uses constructor to inject dependent instances.
Understand dependency injection:
A person (Java instance, caller) needs an ax (Java instance, called)
In the primitive society, there is almost no social division of labor. People (callers) who need an ax can only grind an ax by themselves (called). The corresponding situation is: the caller in the Java program creates the caller himself. Generally, the new keyword is used to call the constructor to create a caller.
When I entered the industrial society, the factory emerged, and the ax was no longer done by ordinary people, but produced in the factory. At this time, the ax user (caller) was needed to find the factory and buy the ax, there is no need to care about the manufacturing process of the ax. 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 caller.
To enter the "Communist" Society, an ax is required, and no one even needs to locate the factory. The caller does not need to care about the implementation of the called, but does not need to care about the factory and wait for Spring dependency injection.
Ii. Set Value Injection
Person interface: public interface Person {// defines the method for using an ax public void useAxe ();} Spring recommends interface-oriented programming, which can better isolate specifications and implementations, this provides better decoupling. For a Java EE application, both DAO components and business logic components should first define an interface that defines the functions that the component should implement, however, the implementation of the function is provided by its implementation class.
Axe interface: public interface Axe {// Axe interface has a public String chop ();}
Implement Axe: public class StoneAxe implements Axe {public String chop () {return "";}}
Bean. xml:
<? Xml version = "1.0" encoding = "UTF-8"?> <! -- The root element of the Spring configuration file, using spring-beans-3.0.xsd semantic constraints --> <beans xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://www.springframework.org/schema/beans" xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <! -- Configure a chinese instance --> <bean id = "chinese" class = "com. Chinese"> <! -- Inject stoneAxe to the axe attribute --> <property name = "axe" ref = "stoneAxe"/> </bean> <! -- Configure the stoneAxe instance --> <bean id = "stoneAxe" class = "com. StoneAxe"/> </beans>
Test class:
Public class BeanTest {public static void main (String [] args) {// create Spring container ApplicationContext ctx = new ClassPathXmlApplicationContext ("bean. xml "); // obtain the chinese instance Person p = ctx. getBean ("chinese", Person. class); // call the useAxe () method p. useAxe ();}}
Spring uses XML as the configuration file. Starting from Spring2.0, Spring can use DTD to define the semantic constraints of the configuration file, and can also be defined using XML Schema (the scalability of the Spring configuration file can be used, it further simplifies Spring configuration, provides some new labels, and allows programmers to develop custom configuration file labels so that other developers can use these labels in the Spring configuration file: usually completed by a third-party supplier );
Org. springframwork. beans, org. springframework. various *. xsd file (XML Schema semantic constraint file in the Spring configuration file)
In the configuration file, Spring Bean configuration instances usually specify:
Id: Specifies 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. This interface cannot be used here. You must use the implementation class Spring container to read this attribute using the XML Parser and use reflection to create an instance of this implementation class.
Spring automatically takes over each <bean... /> <property... /> element definition. Spring will call the parameter-free constructor, create the default Bean instance, and call the corresponding setter method to inject the property value to the program.
The id attribute of each Bean is the unique identifier of the Bean. The program accesses the Bean through the id attribute, and the dependencies between the Bean and the Bean are also associated through the id attribute.
The dependencies between Bean and Bean are managed by Spring. Spring uses the setter method to inject the Bean to which the target Bean depends. This method is called set value injection.
Three basic points for using Spring IoC containers:
Interface-oriented programming for each component of the application
The components of the application are not generated by the program, but are generated and initialized by the Spring container.
Spring uses configuration files or Annotation to manage Bean implementation classes and dependencies. Spring containers create instances based on configuration files and reflection, and inject dependencies to them.
Iii. Construction Injection
When constructing an instance, you have initialized the dependency for it. This method uses the constructor to set dependencies, which is called constructor injection.
Public class Chinese implements Person {private Axe axe; // default constructor public Chinese () {}// public Chinese (Axe axe) {this. axe = axe;} // useAxe method for implementing the Person interface @ Override public void useAxe () {// call axe's chop () method // indicates that the Person object depends on the axe object System. out. println (axe. chop ());}}
You no longer need to provide the setter method for setting the axe attribute. It only provides a constructor with the Axe attribute. Spring will inject the Bean instances that are dependent on the chinese language through this constructor.
<? Xml version = "1.0" encoding = "UTF-8"?> <! -- The root element of the Spring configuration file, using spring-beans-3.0.xsd semantic constraints --> <beans xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://www.springframework.org/schema/beans" xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <! -- Configure a chinese instance --> <bean id = "chinese" class = "com. Chinese"> <! -- Use constructor injection to inject stoneAxe instances to chinese instances --> <constructor-arg ref = "stoneAxe"/> </bean> <! -- Configure the stoneAxe instance --> <bean id = "stoneAxe" class = "com. StoneAxe"/> </beans>
<Constructor-arg... /> the element specifies a constructor parameter. The parameter type is Axe. This specifies that Spring calls the constructor with an Axe parameter in the Chinese class to create a chinese instance, the constructor with parameters is used to create an instance. Therefore, after the Bean instance is created, the dependencies of the Bean have been set.
Configure <constructor-arg... /> You can specify an index attribute when an element is used to specify the value of this constructor as the number of constructor parameter values; for example, index = "0" indicates that the constructed parameter value will be used as the first constructed parameter.
The execution effect is exactly the same as that when the set injection is used. The difference is that the Axe attribute is different when the Person instance is created. You can use the non-parameter constructor to create a Bean instance and then call the corresponding setter method to inject dependencies; the constructor with parameters is called directly. After the Bean instance is created, the dependency injection has been completed.
Iv. Comparison of the two injection methods
In contrast, set-value injection has the following advantages:
Similar to the traditional method of writing JavaBean, it is easier for program developers to understand, accept, and set dependencies through the setter method.
If constructor injection is used for complex dependencies, the constructor will be too bloated and difficult to read. When creating Bean instances, Spring needs to instantiate all the dependent instances at the same time, this causes performance degradation.
The multi-parameter constructor is more bulky, especially when some attributes are optional.
In contrast, constructor injection has the following advantages:
The injection sequence of dependency can be determined in the constructor, and priority injection of dependency can be prioritized.
For beans with no dependency changes, constructor injection is more useful. Because there is no setter method, all dependencies are set in the constructor. Therefore, you do not have to worry about subsequent code damages dependencies.
The dependency can only be set in the constructor. Only the creator of the component can change the dependency of the component. For component callers, the dependencies inside the component are completely transparent and more consistent with the high cohesion principle.
Generally, a value-based injection policy, supplemented by construction injection, is adopted. For injection that does not need to change dependencies, try to adopt construction injection. For injection of other dependencies, consider setting value injection.
If you have any questions, please leave a message or go to the community on this site for discussion. Thank you for reading this article. Thank you for your support!