Three core learning of spring (2)--dependency injection

         The second feature of spring is dependency injection.

         To learn dependency injection, you should first understand two questions: 1. Who depends on whom; 2. Who injects and what?

         First look at the code:

         Or this bean:

 

package testSpring.business.bean;

import org.springframework.stereotype.Repository;

import testSpring.business.iface.IPrint;

/**  
 *  UserBean :
 * @author xuejupo  [email protected]
 * create in 2016-2-16 9:22:39 am    
 */
public class UserBean implements IPrint{
	@Override
	public String printObject() {
		// TODO Auto-generated method stub
		System.out.println("Print object UserBean:");
		return "abc";
	}

}

 Then, my business logic needs to use the above bean in this bean:

 

 

package testSpring.business.impl;

import testSpring.business.iface.IPrint;

/**  
 *  Print :
 * @author xuejupo  [email protected]
 * create in 2016-2-16 10:23:37 am    
 */

public class Print {
	//Beans that need to be printed, the entry to inject (objects that need to be injected)
	private IPrint printBean;
	private String name;
	public void print(){
		System.out.println("Injected name:"+name);
		this.printBean.printObject();
	}
	
	/**  
	* setPrintBean: set method, a necessary method for set injection
	* @param printBean
	* void return type   
	*/
	public void setPrintBean(IPrint printBean){
		this.printBean = printBean;
	}
	
	/**  
	* setName: set method, a necessary method for set injection
	* @param name
	* void return type   
	*/
	public void setName(String name){
		this.name = name;
	}
}

     Normal client code using the print class:

Print p = new Print();
p.setPrintBean (new UserBean ());
print.print();

     It is also a very simple code, but the client code is strongly coupled with the code of the specific class print and userbean, which does not conform to the open-closed principle, so it is necessary to use dependency injection to inject the Pring object into the client code, and then to Print Inject the Userbean object into the class.

 

        The xml file is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
	http://www.springframework.org/schema/aop  
	http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-3.2.xsd">
	<context:annotation-config/>
	<!-- register javabean -->
	<bean id="userBean" class="testSpring.business.bean.MyBean" />
	
	<!-- register javabean -->
	<bean id="printBean" class="testSpring.business.impl.Print" >
	<!-- Parameters injected into javabean -->
		<property name = "printBean" ref = "userBean"></property>
		<property name = "name" value = "haha"></property>
	</bean>
</beans>

 Client code:

//Read the configuration file (load the beans in the configuration file into memory)
		ApplicationContext ctx = new ClassPathXmlApplicationContext("/testSpring/resources/applicationContext.xml");
		// get the instance
		Print bean=(Print)ctx.getBean("printBean");  
		// call the method  
		bean.print();

 print result:

Injected name: haha
Print object MyBean:

       It can be seen that using the configuration information of xml, no specific new java objects are needed in the client code. The creation of java objects and the assignment of elements in objects can be handled by xml (spring).

 

        Answer the first two questions in the article: 1. In the client code, the creation of specific objects depends on the xml file (spring, that is, the IOC container); 2. It is the injection of the IOC container. During the runtime, according to the configuration information of the xml, the specific object is injected. The object is injected into the corresponding bean.

       Tell me about the IOC container in my understanding: I have searched on the Internet, and there is no answer that satisfies me. I can only understand it myself. The IOC container I understand is actually that after the web service is started, tomcat (or other web server) loads applicationContext.xml (spring configuration file of registered bean), and will open up a memory area in memory to store it in the xml file. bean, and is stored in the form of map mapping, the key is the id, and the value is the specific bean. This memory area, the container used to store beans, is called the IOC container (in fact, it should be called the spring bean container) (personal understanding, I really can't find a better explanation for this definition, so I can only understand it first).

        If you have read my previous blog, you will definitely say that dependency injection and inversion of control are different. . . . They are indeed the same thing. . . Dependency injection can also be called inversion of control, which is to give control to the configuration file. . But I personally like to understand it this way: the registration of beans is called inversion of control, and the initialization of parameters in beans is called dependency injection. Personally, I think it is enough to know that it is one thing, and how easy it is for you to understand how to come.

       Talk about the benefits of dependency injection:

       The most important thing is decoupling. It is convenient to switch data sources: for example, if I want to print another bean in the print class, I only need to modify the xml file.

       This is still a bit false, and the real environment may be more indicative of the problem: The company has recently encountered a demand that requires two groups of people to jointly develop: a wave of development of the company's internal network interface---group A, and a wave of development of the company's external implementation (equivalent to on the client) --- Group B. Client development depends on the function of the intranet, but it cannot wait for the students in the intranet to complete the development first, so the leader decided: the people in group A should first expose the functions that need to be implemented to B in the form of interfaces. The students in the group, and then the two groups are independent, and they can be merged after the development is completed.

        Suppose group A exposes an interface as follows:

public interface MyInterface{
        void myMethod();
}

        But the implementation of this interface in group A has not been written yet, so people in group B want to use this interface to program, there are two ways (I am a novice, there may be other ways, you can give pointers):

 

        First:

 

MyInterface bean = null;//The specific interface implementation needs to be filled later here

        Then, when group A gives us the implementation, we assign all beans to specific implementations through a global search. At this time, in case the people in group A twitched their minds and said, oops, the implementation I gave you is wrong, it should be given to group C, and you use another one, then I have to modify all the codes globally. . . . (This is strong coupling. If group A modifies the code, the code of group B must be modified)

 

        Then, the second is the sauce:

         With a configuration file:

<bean id="myInterface" class="xxx.xxx.xxx.xxxx" />
<!-- register my javabean -->
	<bean id="printBean" class="testSpring.business.impl.Print" >
	<!-- inject interface implementation -->
		<property name = "myInterface" ref = "myInterface"></property>
	</bean>

 

     Then in my already registered javaBean just need this:

private MyInterface myInterface;

 

     You can use the specific implementation of the interface, and no matter how you change group A, the code of group B does not need to be modified, only the configuration file is changed (of course, the premise is that the interface of group A cannot be changed). This is weak coupling and design. The famous Dependency Inversion Principle (depending on the interface and not on the concrete implementation).

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327090556&siteId=291194637