Spring Dependency Injection

1: In order to reduce the complexity of Java development, Spring adopts 4 key strategies
    : lightweight and minimally invasive programming through POJO;
    loose coupling through dependency injection and interface-oriented;
    declarative programming based on aspects and conventions;
    through aspects and templates to reduce boilerplate code;
Spring strives to avoid cluttering application code with its own API, and does not force you to implement Spring-specific interfaces or extend Spring-specific classes. Conversely, in an application built on Spring, its classes usually have no trace that you are using Spring. In the worst case, a class may use Spring annotations, but it is still POJO.
From this point of view, both configuration and annotation have their own advantages and disadvantages. Although configuration is slightly cumbersome, it is independent of the code. Although annotations are convenient for rapid development, they still have a certain degree of coupling.
Example 1:
public class Student1 implements Person{
	private Teacher teacher;

	public Student1() {
		this.teacher = new Teacher();//Tightly coupled with Teacher
	}
	
	public void study() {
		teacher.teach();
	}
}

Example 2:

public class Student implements Person{
	private Teacher teacher;

	public Student(Teacher teacher) {
		this.teacher = teacher;
	}
	
	public void study() {
		teacher.teach();
	}
}

These two examples briefly show the limitations brought by tight coupling. Example 2 does not pass an object by itself, but passes in the task as a constructor parameter during construction, which is one of the ways of dependency injection. Constructor injection
and then expand, if the teacher in example 1 is a physical education teacher or an art teacher, and the teacher in example 2 is all teachers, then the disadvantage of example 1 will be more prominent, while example 2 can be different accordingly The operation of the teacher is not coupled with any specific teacher, he does not care which specific teacher, this is the biggest benefit of DI [dependency injection] - loose coupling. If an object expresses dependencies only through interfaces (rather than concrete implementations or initialization procedures), then such dependencies can be replaced by different concrete implementations without the object's knowledge.
  However, coupling concrete two-sidedness. On the one hand, tightly coupled code is difficult to test, reuse, and understand, and typically exhibits the bug characteristics of "whack-a-mole". After fixing one bug, other bugs will appear. On the other hand, some degree of coupling is necessary, and code that is completely uncoupled can't do anything. In order to perform meaningful functions, different classes must interact in an appropriate way. All in all, coupling is necessary, but should be used with care.
         So, how to pass a specific teacher to the student, the act of creating collaboration between application components is often called assembly.
Spring has a variety of ways to wire beans, and XML is common. The following example shows:
package com.spring.dao;

public interface TeacherDao {
	
	public void teach();
}

Teacher implementation class:
import com.spring.dao.TeacherDao;

public class TeacherDaoImple implements TeacherDao{

	public void teach() {
		System.out.println("The teacher is lecturing");
	}
}

Student class:
import com.spring.dao.TeacherDao;

public class StudentService{

	private TeacherDao teacherDao;
	
	public void setTeacherDao(TeacherDao teacherDao) {
		this.teacherDao = teacherDao;
	}
	
	public void lean() {
		teacherDao.teach();
	}

}

XML placement:
<?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="studentService"  class="com.spring.service.StudentService">
		<property name="teacherDao"  ref="teacher"></property>
	</bean>
	<bean id="teacher" class="com.spring.dao.imple.TeacherDaoImple"></bean>
	
</beans>

Test class:
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.service.StudentService;

public class StudentTest {
	private ApplicationContext atc =  new ClassPathXmlApplicationContext("Student.xml");

	@Test
	public void test1(){
		StudentService stu = atc.getBean(StudentService.class);
		stu.lean();	
	}
}
Test Results:
信息: Loading XML bean definitions from class path resource [Student.xml]
teacher is lecturing

Spring also supports the use of JAVA to describe configuration. Its role is the same as XML.
import javax.annotation.Resource;
import org.springframework.stereotype.Component;

@Component(value="student")
public class Student implements Person{
	@Resource
	private Teacher teacher;

	public Student(Teacher teacher) {
		this.teacher = teacher;
	}
	
	public void study() {
		teacher.teach();
	}
}

Although Student relies on Teacher, he does not know what specific type of teacher is passed to him, nor where it comes from. Only Spring can understand how these components are assembled through his configuration. In this case, It is possible to modify dependencies without changing the dependent classes.
Here, the Spring application context is created through the Student.xml file.
    It should be noted here that the Student class needs to have a default constructor that can actually be used. If a constructor with parameters is declared, then a constructor without parameters needs to be declared, otherwise the bean cannot be automatically created.
    When there is a parameterized constructor, no parameterless constructor is declared:
public class StudentService{

	private TeacherDao teacherDao;
	
	public StudentService(TeacherDao teacherDao) {
		super();
		this.teacherDao = teacherDao;
	}

	public void setTeacherDao(TeacherDao teacherDao) {
		this.teacherDao = teacherDao;
	}
	
	public void lean() {
		teacherDao.teach();
	}

}

Test class execution result:
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'studentService' defined in class path resource [Student.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.spring.service.StudentService]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.spring.service.StudentService.<init>()

So it is recommended to always declare a no-argument constructor explicitly:
public class StudentService{

	private TeacherDao teacherDao;
	
	public StudentService() {
		super();
	}

	public StudentService(TeacherDao teacherDao) {
		super();
		this.teacherDao = teacherDao;
	}

	public void setTeacherDao(TeacherDao teacherDao) {
		this.teacherDao = teacherDao;
	}
	
	public void lean() {
		teacherDao.teach();
	}

}

Test class execution result:
信息: Loading XML bean definitions from class path resource [Student.xml]
teacher is lecturing

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324462520&siteId=291194637