Article Directory
Setter injection method is used the most
- The Spring development team generally advocates using constructor injection when the implemented application component is an immutable object and ensuring that the required dependencies are not null.
- On the other hand, a large number of constructor parameters cause bad code smell, which indicates that the class may take on too many responsibilities and should need to be refactored in order to better separate the problems to be solved.
- One of the benefits of setter injection is that the setter method allows objects of this class to be reasonably reconfigured or re-injected at some point in the future, and the readability is good
Constructor injection
Injection through construction method
Project structure
Teacher.java
package com;
public class Teacher {
private int id;
private String name;
//无参数
public Teacher() {
}
//有参数
public Teacher(int id, String name) {
this.id = id;
this.name = name;
}
public void show() {
System.out.println("id:"+id+",name:"+name);
}
}
Test.java
package com;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
Teacher t = (Teacher)ctx.getBean("Teacher");
t.show();
}
}
Beans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 构造器注入形式1,简单但是对顺序与数量有要求,必须与Teacher类一致才行 -->
<!--
<bean id="Teacher" class="com.Teacher">
<constructor-arg value="1"></constructor-arg>
<constructor-arg value="zhangSan"></constructor-arg>
</bean>
-->
<!-- 构造器注入形式2,通过id属性确定赋值目标 -->
<!--
<bean id="Teacher" class="com.Teacher">
<constructor-arg index="0" value="1"></constructor-arg>
<constructor-arg index="1" value="zhangsan"></constructor-arg>
</bean>
-->
<!-- 构造器注入形式3,通过name属性确定赋值目标 -->
<!--
<bean id="Teacher" class="com.Teacher">
<constructor-arg name="id" value="1"></constructor-arg>
<constructor-arg name="name" value="zhangsan"></constructor-arg>
</bean>
-->
</beans>
Pros and cons
The code is simple, but the readability is poor.
Setter method injection
- After calling the no-parameter constructor or the no-parameter static factory method to instantiate the bean, the container can complete dependency injection by calling back the bean's setter method.
If the injected is a reference type, use the ref attribute, and the parameter is the id of the bean defined above;
Simple type of injection
Project structure
DiClass.java
package com;
import java.sql.DriverManager;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class DiClass {
private int id;
private String name;
private Teacher teacher;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public void show() {
System.out.println(id);
System.out.println(name);
System.out.println("==========================");
teacher.show();
}
}
Teacher.java
package com;
public class Teacher {
private int id;
private String name;
//无参数
public Teacher() {
}
//有参数
public Teacher(int id, String name) {
this.id = id;
this.name = name;
}
public void show() {
System.out.println("id:"+id+",name:"+name);
}
}
Test.java
package com;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
DiClass dc = (DiClass)ctx.getBean("DiClass");
dc.show();
}
}
Beans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 构造器注入形式1,简单但是对顺序与数量有要求,必须与Teacher类一致才行 -->
<!--
<bean id="Teacher" class="com.Teacher">
<constructor-arg value="1"></constructor-arg>
<constructor-arg value="zhangSan"></constructor-arg>
</bean>
-->
<!-- 构造器注入形式2,通过id属性确定赋值目标 -->
<!--
<bean id="Teacher" class="com.Teacher">
<constructor-arg index="0" value="1"></constructor-arg>
<constructor-arg index="1" value="zhangsan"></constructor-arg>
</bean>
-->
<!-- 构造器注入形式3,通过name属性确定赋值目标 -->
<bean id="Teacher" class="com.Teacher">
<constructor-arg name="id" value="1"></constructor-arg>
<constructor-arg name="name" value="zhangsan"></constructor-arg>
</bean>
---------------------------------------------------------------
<!-- ref的参数是上面定义的Bean的id -->
<bean id="DiClass" class="com.DiClass">
<property name="id" value="100"></property>
<property name="name" value="lisi"></property>
<property name="teacher" ref="Teacher" ></property>
</bean>
</beans>
Complex type injection
Reference Data Type & Anonymous Inner Class/Inner Bean
The second is an anonymous inner class, which can only be used in a small area.
List and array
package com;
import java.sql.DriverManager;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class DiClass {
private List bookName;
private Set hobby;
public void setBookName(List bookName) {
this.bookName = bookName;
}
}
<!-- List类型与数组类型 -->
<property name="bookName">
<list>
<value>Java</value>
<value>c#</value>
<!-- ref=上面的自定义ID -->
<ref bean="Teacher"/>
</list>
</property>
Set
private Set hobby;
public void setHobby(Set hobby) {
this.hobby = hobby;
}
<!-- set类型,不会放重复的数据 -->
<property name="hobby">
<set>
<value>book</value>
<value>football</value>
<ref bean="Teacher"/>
<value>book</value>
</set>
</property>
Map
private Set hobby;
private Map map;
public void setMap(Map map) {
this.map = map;
}
<!-- HashMap -->
<property name="map">
<map>
<!-- key=键 ,value=数值 -->
<entry key="a" value="100"></entry>
<!-- key-ref=引用数据类型,加上ref的都是Bean的引用数据类型 -->
<entry key-ref="Teacher" value="200"></entry>
<entry key="b" value-ref="Teacher"></entry>
</map>
</property>
Properties
Set merge
Simulate Java inheritance
The abstract attribute is defined as abstract, it is no longer concretely instantiated, and is mostly used in templates