catalogue
Concept of dependency injection
Modify the TestHello class again
Two ways of dependency injection
Comparison of two injection methods
Concept of dependency injection
The core mechanism of Spring is dependency injection (DI), also known as inversion of control (IOC).
This article continues from the previous one Introduction to Spring development
First, create a common class
package org.example; public class TestDao { public String test(){ return "I don't know what to do?"; } }
Modify the TestHello class again
package org.example; public class TestHello { private TestDao testDao; //Must have public void setTestDao(TestDao testDao) { this.testDao = testDao; } public void testHello(){ System.out.println(testDao.test()); } }
Modify profile
Modify the applicationContext.xml file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="TestHello" class="org.example.TestHello"> <!--property Element is used to specify the attributes that need container injection. Here is set value injection, so TestHello Class must have setTestDao method--> <property name="TestDao"> <!--Another one will be here bean Reference injection to TestHello bean--> <ref bean="TestDao"></ref> </property> </bean> <bean id="TestDao" class="org.example.TestDao"> </bean> </beans>
Writing test classes
package org.example; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main( String[] args ) { //Get ApplicationContext object ApplicationContext application=new ClassPathXmlApplicationContext("ApplicationContext.xml"); //Get TestHello object through ApplicationContext //The parameter in the getBean () method is the value of the Bean id in the configuration file TestHello testHello=(TestHello) application.getBean("TestHello"); testHello.testHello(); } }
Operation results
analysis
Normally, we need to call the methods in TestDao through
//Create TestHello real column TestDao testDao=new TestDao(); //Call method testDao.test();
However, in the above program, there is no TestHello instance and TestDao instance coupled together. That is, the program does not create a new TestDao instance in the TestHello instance. The TestDao instance is dynamically "injected" into the TestHello instance by Spring during runtime. When the program runs to the point where it needs a TestDao instance, Spring creates it and injects it into the caller who needs it. When the TestHello instance runs where the TestDao instance is needed, TestDao is naturally generated for its use. This way of generating instances is called dependency injection. It can be found that when TestDao is applied in TestHello, the setter method of its instance is generated, and Spring creates an instance of TestDao through this setter method.
Two ways of dependency injection
set injection
set injection is described above, and structure injection is described below.
Structural injection
Construction injection refers to defining a construction method in the injected class and defining the elements to be injected in the parameters of the construction method.
Continue with the above example. First, modify the TestHello.java class and add a constructor to the class
package org.example; public class TestHello { private String message; //Construction method public TestHello(String message) { this.message = message;//Structural injection } public String getMessage() { return message; } }
Modify the ApplicationContext.xml file
Constructor Arg: indicates that dependency injection is carried out through construction; index=0: indicates the first parameter in the construction method, which can be omitted. If there are multiple parameters, simply configure constructor Arg repeatedly, but change the value of index. For example, if there is also a parameter sex in the TestHello class, and the value is injected into it through the construction method:
public TestHello(String message,String sex) { this.message = message;//Structural injection this.sex=sex; }
Then you need to add a constructor Arg to the configuration file ApplicationContext.xml
<bean id="TestHello" class="org.example.TestHello"> <constructor-arg index="0"> <value>I know what I'm doing! Learning, of course!</value> </constructor-arg> <constructor-arg index="1"> <value>female</value> </constructor-arg> </bean>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="TestHello" class="org.example.TestHello"> <constructor-arg index="0"> <value>I know what I'm doing! Learning, of course!</value> </constructor-arg> </bean> </beans>
Operation results
Comparison of two injection methods
Using construction injection can complete the establishment of dependencies while building objects. Therefore, if there are many relationships of objects to be established, using construction injection will leave many parameters on the construction method, and the method readability is poor. It is recommended to use set injection. However, with set injection, because the setXX() method is provided, it can not guarantee that the relevant data will not be changed during execution. Therefore, if you want to make some data read-only or private, using construct injection will be a good choice.