相关文章链接:
观前提示:
本文所使用Eclipse版本为Photon Release (4.8.0),JDK版本为1.8.0_141,Tomcat版本为9.0.12。
1.接口注入(不推荐)
从注入方式的使用上来说,接口注入是现在不提倡的一种方式,基本处于“退役状态”。因为它强制被注入对象实现不必要的接口,带有侵入性。而构造方法注入和setter方法注入则不需要如此。
2.构造方法注入
将依赖关系作为构造函数参数传入的做法称为构造器注入(Constructor Injection)。这种注入方式的优点就是,对象在构造完成之后,即已进入就绪状态,可以马上使用。缺点就是,当依赖对象比较多的时候,构造方法的参数列表会比较长。而通过反射构造对象的时候,对相同类型的参数的处理会比较困难,维护和使用上也比较麻烦。而且在Java中,构造方法无法被继承,无法设置默认值。对于非必须的依赖处理,可能需要引入多个构造方法,而参数数量的变动可能造成维护上的不便。
2.1 例子
applicationContext.xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- 构造器注入 -->
<bean id="userConstructor" class="cn.com.demo.User">
<constructor-arg value="1"/>
<constructor-arg value="user1"/>
</bean>
</beans>
在进行构造器注入的时候,也可以用index来定义构造器中参数的顺序。
<bean id="userConstructor" class="cn.com.demo.User">
<constructor-arg value="1" index="0"/>
<constructor-arg value="user1" index="1"/>
</bean>
也可以通过属性的类型进行定义。
<bean id="userConstructor" class="cn.com.demo.User">
<constructor-arg value="1" type="java.lang.String"/>
<constructor-arg value="user1" type="java.lang.String"/>
</bean>
也可以通过属性名进行注入值。
<bean id="userConstructor" class="cn.com.demo.User">
<constructor-arg value="1" name="userID"/>
<constructor-arg value="user1" name="userName"/>
</bean>
User.java
package cn.com.demo;
public class User {
private String userID;
private String userName;
public User(String userID, String userName) {
this.userID = userID;
this.userName = userName;
}
@Override
public String toString() {
return "User [userID=" + userID + ", userName=" + userName + "]";
}
}
测试类TestConstructor.java
package cn.com.test;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.com.demo.User;
public class TestConstructor {
private ClassPathXmlApplicationContext ac;
@Before
public void before() {
ac = new ClassPathXmlApplicationContext("*/applicationContext.xml");
}
@Test
public void test() {
try {
User user = (User) ac.getBean("userConstructor");
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果
3.setter方法注入
通过JavaBean属性注射依赖关系的做法称为设值方法注入(Setter Injection)。因为方法可以命名,所以setter方法注入在描述性上要比构造方法注入好一些。 另外,setter方法可以被继承,允许设置默认值,而且有良好的IDE支持。缺点当然就是对象无法在构造完成后马上进入就绪状态。其实,这些操作都是由IoC容器来做的,我们所要做的,就是调用IoC容器来获得对象而已。
3.1 例1 Setter注入Bean
applicationContext.xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<!-- setter注入bean -->
<bean id="user" class="cn.com.demo.User"/>
<bean id="personSetter" class="cn.com.demo.Person">
<!--构造注入user-->
<property name="user" ref="user"/>
</bean>
</beans>
User.java
package cn.com.demo;
public class User {
public void getUser() {
System.out.println("这是setter注入bean");
}
}
Person .java
package cn.com.demo;
public class Person {
private User user;
//setter方式注入bean
public void setUser(User user) {
this.user = user;
};
public void getPerson() {
user.getUser();
}
}
测试类TestSetter.java
package cn.com.test;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.com.demo.Person;
public class TestSetter {