依赖注入

/ Spring / 没有评论 / 299浏览

在之前的文章中我们简单介绍了spring框架中IOC容器的依赖注入,并演示了属性注入、构造方法注入、接口注入等方式的使用。在这篇文章中我们将详细了解IOC容器依赖注入的使用,及注意事项。

public class User {

private String username;
private String password;

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
<bean id="user" class="com.jilinwula.spring.User" p:username="admin" p:password="jilinwula"/>
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
}
User{username='admin', password='jilinwula'}

属性注入比较简单,只要直接在bean标签中设置属性的值就可以自动完成注入,实际上IOC容器底层调用的是该属性的set方法。所以属性注入有一点要特别注意,就是它只和属性的set方法有关,而和实体类中的属性名字没有直接关系。我们通过下面的测试来证明我们所说的。

public class User {

private String password;
private String nickName;

public void setUsername(String username) {
this.nickName = username;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return "User{" +
"password='" + password + '\'' +
", nickName='" + nickName + '\'' +
'}';
}
}
<bean id="user" class="com.jilinwula.spring.User" p:username="admin" p:password="jilinwula"/>
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
}
User{password='jilinwula', nickName='admin'}

虽然我们已经在xml中设置了username的属性值,但是我们知道实体类中并没有usename属性,而是只有setUsername方法,并且在setUsername方法中我们处理的逻辑是给nickName属性赋值,如果IOC容器成功把值注入到nickName属性中,则证明了我们上述所说的,也就是属性注入只和set方法有关,而和属性名称没有关系。看输出结果看,正好证明我们上述的的观点。

public class User {

private String username;
private String password;
private int age;

public User() {
}

public User(String username, int age) {
this.username = username;
this.age = age;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", age='" + age + '\'' +
'}';
}
}
<bean id="user" class="com.jilinwula.spring.User">
<constructor-arg type="java.lang.String">
<value>admin</value>
</constructor-arg>
<constructor-arg type="int">
<value>29</value>
</constructor-arg>
</bean>
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
}
User{username='admin', password='null', age='29'}
<bean id="user" class="com.jilinwula.spring.User">
<constructor-arg index="0">
<value>admin</value>
</constructor-arg>
<constructor-arg index="1">
<value>password</value>
</constructor-arg>
<constructor-arg index="2">
<value>29</value>
</constructor-arg>
</bean>
User{username='admin', password='password', age=29}

构造函数注入这两种方式都可以,但有些时候,我们必须集合这两种主式才可以完成注入,请看下面的测试用例。

public class User {

private String username;
private String password;
private String nickName;
private int age;

public User() {
}

public User(String username, int age) {
this.username = username;
this.age = age;
}

public User(String username, String password, String nickName) {
this.username = username;
this.password = password;
this.nickName = nickName;
}

public User(String username, String password, int age) {
this.username = username;
this.password = password;
this.age = age;
}

public String getNickName() {
return nickName;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public void setNickName(String nickName) {
this.nickName = nickName;
}

@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
", nickName='" + nickName + '\'' +
'}';
}
}
<bean id="user" class="com.jilinwula.spring.User">
<constructor-arg index="0">
<value>admin</value>
</constructor-arg>
<constructor-arg index="1">
<value>password</value>
</constructor-arg>
<constructor-arg index="2">
<value>209</value>
</constructor-arg>
</bean>
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
}
User{username='admin', password='password', age=0, nickName='209'}

我们看输出已经将xml中的第3个配置参数自动注入给nickName属性了,如果我们想将xml中的第3个参数注入到age属性中,则可以采用索引加类型的方式匹配参数。

<bean id="user" class="com.jilinwula.spring.User">
<constructor-arg index="0" type="java.lang.String">
<value>admin</value>
</constructor-arg>
<constructor-arg index="1" type="java.lang.String">
<value>password</value>
</constructor-arg>
<constructor-arg index="2" type="int">
<value>209</value>
</constructor-arg>
</bean>
User{username='admin', password='password', age=209, nickName='null'}
public class UserFactory {
public User createUser() {
User user = new User();
user.setUsername("admin");
user.setNickName("管理员");
user.setPassword("jilinwula");
user.setAge(10);
return user;
}
}
public class User {

private String username;
private String password;
private String nickName;
private int age;

public User() {
}

public User(String username, int age) {
this.username = username;
this.age = age;
}

public User(String username, String password, String nickName) {
this.username = username;
this.password = password;
this.nickName = nickName;
}

public User(String username, String password, int age) {
this.username = username;
this.password = password;
this.age = age;
}

public String getNickName() {
return nickName;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public void setNickName(String nickName) {
this.nickName = nickName;
}

@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
", nickName='" + nickName + '\'' +
'}';
}
}
<bean id="userFactory" class="com.jilinwula.spring.UserFactory"/>
<bean id="user" factory-bean="userFactory" factory-method="createUser"/>
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
}
User{username='admin', password='jilinwula', age=10, nickName='管理员'}
public class UserFactory {
public static User createUser() {
User user = new User();
user.setUsername("admin");
user.setNickName("管理员");
user.setPassword("jilinwula");
user.setAge(10);
return user;
}
}
<bean id="user" class="com.jilinwula.spring.UserFactory" factory-method="createUser"/>
User{username='admin', password='jilinwula', age=10, nickName='管理员'}
public class User {

private String username;
private String password;
private String nickName;
private int age;
private Work work;

public User() {
}

public User(String username, int age) {
this.username = username;
this.age = age;
}

public User(String username, String password, String nickName) {
this.username = username;
this.password = password;
this.nickName = nickName;
}

public User(String username, String password, int age) {
this.username = username;
this.password = password;
this.age = age;
}

public String getNickName() {
return nickName;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public void setNickName(String nickName) {
this.nickName = nickName;
}

public Work getWork() {
return work;
}

public void setWork(Work work) {
this.work = work;
}

@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", nickName='" + nickName + '\'' +
", age=" + age +
", work=" + work +
'}';
}
}
public class Work {
private String address;

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

@Override
public String toString() {
return "Work{" +
"address='" + address + '\'' +
'}';
}
}
<bean id="work" class="com.jilinwula.spring.Work" p:address="北京"/>
<bean id="user" class="com.jilinwula.spring.User" p:username="admin" p:password="jilinwula" p:nickName="管理员" p:age="20" p:work-ref="work"/>
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
}
User{username='admin', password='jilinwula', nickName='管理员', age=20, work=Work{address='北京'}}