Throughout all Java applications, from applet-based small applications to enterprise-class applications with multi-tiered architectures, they are a typical dependency application, which is made up of a number of collaborative objects. Spring calls this collaborative relationship a dependency. If a component calls a method of component B, it can be said that a component relies on the B component dependency injection so that spring beans are organized together in a configuration file instead of being coupled in a hard-coded fashion
I. Understanding Dependency Injection
Dependency Injection (Dependency injection) = control reversal (inversion OFCONTROL,IOC): When a Java instance (caller) needs another Java instance (callee), in Dependency injection mode, The work of creating the callee is no longer done by the caller, so it is called control inversion ; the work of creating the callee instance is usually done by the spring container, which is then injected into the caller, and therefore also called the dependency injection
Dependency Injection: When a program is running, you need to collaborate on another object (calling its methods, accessing his properties) without creating the callee in your code, but instead relying on the injection of the outer container. Spring's dependency injection has virtually no requirement for callers and callers to fully support the management of Pojo dependencies
Dependency Injection
SetPoint injection: The IOC container uses the setter method of the property to inject the dependent instance
Construct injection: The IOC container uses constructors to inject dependent instances
Understanding Dependency Injection:
A person (Java instance, caller) needs an axe (Java instance, callee)
In primitive society, there was hardly any social division of labor; the person who needs the axe (the caller) can only grind an axe (callee) by himself; the corresponding scenario is: The caller of the Java program creates the callee himself, usually using the new keyword to call the constructor to create a callee
Into the industrial society, the factory appeared, the axe is no longer done by ordinary people, and in the factory was produced, at this time the need to axe (the caller) to find factories, buy axes, do not care about the manufacturing process of the axe; corresponding to a simple factory design pattern, callers need to locate the factory without having to manage the specific implementation of the callee
To enter the "Communist" society, people who need an axe do not even have to locate the factory, "Wait for" the society to provide, the caller does not need to care about the caller's implementation, regardless of the factory, waiting for spring dependency injection
Second, set value injection
Person interface: Public interface Person { //define method to use axe public void Useaxe ();} Spring recommends interface-oriented programming, which allows for better decoupling of specifications and implementations, and for a Java EE application, whether it is a DAO component or a business logic component, you should first define an interface that defines the functionality that the component should implement. But the implementation of the feature is provided by its implementation class
Axe interface: public interface Axe { ///AXE interface There is a way to hack public String chop ();}
Implement Person:public class Chinese implements person { private Axe Axe; Set the setter method required for injection public void Setaxe (Axe Axe) { this.axe = Axe; } The Useaxe method that implements the person interface @Override public void Useaxe () { //calls Axe Chop () method //indicates that the person object is dependent on the Axe object System.out.println (Axe.chop ());} } The class does not know where to invoke the axe instance, and does not know how the axe instance is implemented, it only needs to invoke a axe instance, and the axe instance will be injected by the spring container.
Implement Axe:public class Stoneaxe implements Axe {public String chop () { return "stone axe chopping good slow S"; }}
Bean.xml:<?xml version= "1.0" encoding= "UTF-8"?><!--the root element of the spring configuration file, using spring-beans-3.0.xsd semantics 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 Chinese instance --<bean id=" Chinese "class=" com. Chinese "> <!--inject stoneaxe into axe properties-- <property name=" Axe "ref=" Stoneaxe "/> </bean > <!--Configure 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 = NE W Classpathxmlapplicationcontext ("Bean.xml"); Get Chinese instance person p = Ctx.getbean ("Chinese", person.class); Call Useaxe () method p.useaxe ();} }
Spring takes XML as a configuration file, starting with Spring2.0, and spring can use DTDs to define the semantic constraints of the configuration file, or it can be defined with an XML schema (with the extensibility of the spring configuration file, further simplifying the spring configuration Some new tags are also available, allowing programmers to develop custom profile tags that other developers use in spring profiles: typically done by third-party vendors);
Various *.xsd files can be found under the \src\main\resources path of the Org.springframwork.beans, Org.springframework.context, and so on in the Spring Projects directory ( XML Schema semantic constraint file for spring configuration file)
In the configuration file, the spring configuration Bean instance will typically specify:
ID: Specifies the bean's unique identity, and the program accesses the bean instance through the ID property value
class: Specifies the implementation class for the bean, where the interface is no longer available and must be read with an XML parser using the implementation class spring container, and use reflection to create an instance of the implementation class
Spring will automatically take over the <property.../> element definition in each <bean.../> definition, and spring will inject the property value into the program after it calls the parameterless constructor, creates a default bean instance, and calls the corresponding setter method.
The ID property of each bean is the bean's unique identity, and the program accesses the Bean,bean with the bean through the ID property, also through the ID Property Association
The dependencies between beans and beans are managed by spring, and spring uses setter methods to inject the bean that it relies on to the target bean, which is called value injection
3 basic points for using the Spring IOC container:
interface-oriented programming for each component of the application
The components of the application are no longer actively generated by the program, but are generated and initialized by the spring container.
Spring takes a configuration file, or annotation, to manage the bean's implementation classes, dependencies, and the spring container creates instances from the configuration file, leverages reflection, and injects dependencies into them.
Third, construction injection
When the instance is constructed, the dependency initialization 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; The default constructor public Chinese () { } //constructs the required constructor with parameters of public Chinese (Axe Axe) { this.axe = Axe; } The Useaxe method that implements the person interface @Override public void Useaxe () { //calls Axe Chop () method //indicates that the person object is dependent on the Axe object System.out.println (Axe.chop ());} } There is no need to provide a setter method that sets the Axe property, only a constructor with a axe attribute is provided, and spring will inject the dependent bean instance through the constructor for Chinese
<?xml version= "1.0" encoding= "UTF-8"?><!--the root element of the spring configuration file, using spring-beans-3.0.xsd semantics 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 Chinese instance --<bean id=" Chinese "class=" com. Chinese "> <!--using construct injection, inject stoneaxe instance for Chinese instance-- <constructor-arg ref=" Stoneaxe "/> </bean> <!--Configure Stoneaxe instance --<bean id= "stoneaxe" class= "com. Stoneaxe "/> </beans>
<constructor-arg ... The/> element specifies a constructor parameter, which is axe, which specifies that spring calls the constructor of the Chinese class with a axe parameter to create the Chinese instance, because an instance is created with a parameterized constructor, so when the bean instance is created, The bean dependency has been set to complete
Configure <constructor-arg ... The/> element can be specified with an index property that specifies that the construction parameter value will be the number of construction parameter values, such as index= "0" indicating that the construction parameter value will be the first construction 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-----The setting injection is to create a bean instance from the parameterless constructor and then invoke the corresponding setter method to inject the dependency, whereas the construction injection calls the constructor with the argument directly, and when the bean instance is created, The injection of dependency has been completed
Iv. comparison of two injection methods
In contrast, setting value injection has the following advantages:
More similar to the traditional JavaBean, it is easier for program developers to understand, accept, and set up dependency relationships through setter methods, which is more intuitive and natural.
In the case of complex dependencies, the constructor is too bloated and difficult to read if the construction injection is used; Spring creates performance degradation when you create a bean instance by instantiating all of its dependent instances simultaneously
Multi-parameter constructors are more cumbersome, especially if some properties are optional
In contrast, construction injection has the following advantages:
The injection order of dependencies can be determined in the constructor, and priority injection of precedence depends on
Construction injection is more useful for beans that do not need to change dependencies, because there is no setter method, all dependencies are set within the constructor. Therefore, there is no need to worry about subsequent code damage to the dependencies
Dependencies can only be set in the constructor, and only the creator of the component can change the dependencies of the components. For the caller of the component, the dependencies within the component are completely transparent and more consistent with the high cohesion principle
In general, the injection strategy is mainly based on the value injection and the structure injection as a supplement. As far as possible, there is no need to change the dependency of injection, the use of construction injection, while the other dependency on the injection, then consider the value injection
Spring-----3, Spring's core mechanism: Dependency Injection