博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Spring实战系列](7)Spring注入方式之构造器注入
阅读量:5846 次
发布时间:2019-06-19

本文共 4988 字,大约阅读时间需要 16 分钟。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/50630847

1. 构造器注入

基于构造器的注入通过调用带参数的构造器来实现,每个参数代表着一个协作者。

1.1 最简单形式

我们以下面的Student实体类为例进行说明:

 
package com.sjf.bean;
 
/**
* 学生实体类
* @author sjf0115
*
*/
public class Student {
private String name;
private String company;
private int age;
private boolean sex;
public Student(String name, String company, int age, boolean sex) {
this.name = name;
this.company = company;
this.age = age;
this.sex = sex;
}
 
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("个性详细信息如下:" + "\n");
stringBuilder.append("name:" + name + "\n");
stringBuilder.append("company:" + company + "\n");
stringBuilder.append("age:" + age + "\n");
stringBuilder.append("sex:" + (sex ? "boy" : "girl"));
return stringBuilder.toString();
}
}
Student类有四个属性:name,company,age,sex。这四个属性是通过构造器注入来设置。重写Student的toString()方法来展示Student对象信息。
 
<?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 = "yoona" class = "com.sjf.bean.Student">
<constructor-arg value = "yoona"/>
<constructor-arg value = "Facebook"/>
<constructor-arg value = "24"/>
<constructor-arg value = "true"/>
</bean>
 
</beans>
运行结果:
 
name:yoona
company:Facebook
age:24
sex:true
1.2 根据type属性传值
bean中的constructor-arg元素用于通过构造器注入来设置属性。因为Student类中只有一个构造器,所以该代码没有任何问题。当有相同个数的构造器时,将会出现冲突。考虑如下:
我们为Student类提供了
两个构造器:
 
public Student(String name, String company) {
this.name = name;
this.company = company;
}
 
public Student(String name, int age) {
this.name = name;
this.age = age;
}
配置文件:
 
<bean id = "yoona" class = "com.sjf.bean.Student">
<constructor-arg value = "yoona"/>
<constructor-arg value = "24"/>
</bean>
那么现在你认为哪个构造器将被调用?按照我们的思维应该是第二个带String和int参数的构造器,真的吗?实际上Spring将调用第一个构造器。即使我们知道第一个参数是String,第二个参数是int,但是Spring将其都解析为String。
运行结果:
 
name:yoona
company:24
针对上面的这种情况,我们可以在构造器参数定义中使用type属性来显式的指定参数所对应的简单类型。现在如下配置,第二个构造器将被调用:
 
<bean id = "yoona" class = "com.sjf.bean.Student">
<constructor-arg type = "java.lang.String" value = "yoona"/>
<constructor-arg type = "int" value = "24"/>
</bean>
这样设置之后value="24"则是int类型,不会被认为是String,所以只能匹配 
public
Student
(
String
name
,
int
age
)
 构造器。
运行结果:
 
name:yoona
age:24

1.3 根据index属性传值

通过使用index属性可以显式的指定构造器参数出现顺序。指定构造器参数索引是使用构造器IoC首选的方式。

那么现在考虑如下情况。我们在Student类中有如下的构造器

 
public Student( int age, String company) {
this.company = company;
this.age = age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
进行如下配置:
 
<bean id = "yoona" class = "com.sjf.bean.Student">
<constructor-arg type = "java.lang.String" value = "yoona"/>
<constructor-arg type = "int" value = "24"/>
</bean>
那么现在你认为哪个构造器将被调用?第二个?但是实际上调用了第一个构造器。在调用构造器,配置文件中定义的参数顺序并没有先后之分。
运行结果:
 
company:yoona
age:24
要解决该问题,需要指定index属性,配置如下:
 
<bean id = "yoona" class = "com.sjf.bean.Student">
<constructor-arg index = "0" value = "yoona"/>
<constructor-arg index = "1" value = "24"/>
</bean>
这样设置之后,value="yoona" 必须对应构造器中的第一个参数,所以只能匹配 
public
Student
(
String
name
,
int
age
)
 构造器。
运行结果:
 
name:yoona
age:24
1.4 根据name属性传值

其实还有一个得推荐的方式:根据name属性进行匹配。针对上面的构造器我们使用name属性进行配置如下:

 
<bean id = "yoona" class = "com.sjf.bean.Student">
<constructor-arg name = "name" value = "yoona"/>
<constructor-arg name = "age" value = "24"/>
</bean>
这样配置之后,value="yoona" 只能对应name属性,value="24"只能对应age属性。
运行结果:
 
name:yoona
age:24

1.5 通过构造器注入对象引用

我们为Student提供一个学校实体类:

 
package com.sjf.bean;
 
/**
* 学校实体类
* @author sjf0115
*
*/
public class School {
private String name;
private String location;
public School(String name, String location) {
this.name = name;
this.location = location;
}
 
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("name:" + name);
stringBuilder.append(" location:" + location);
return stringBuilder.toString();
}
}
我们使用构造器注入的方式School类进行配置:
 
<bean id = "xidian" class = "com.sjf.bean.School">
<constructor-arg index = "0" value = "西电"/>
<constructor-arg index = "1" value = "西安"/>
</bean>
 
package com.sjf.bean;
 
/**
* 学生实体类
* @author sjf0115
*
*/
public class Student {
private String name;
private School school;
private int age;
public Student(String name, School school, int age) {
this.name = name;
this.school = school;
this.age = age;
}
 
 
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("个人详细信息如下:" + "\n");
stringBuilder.append("name:" + name + "\n");
stringBuilder.append("age:" + age + "\n");
stringBuilder.append("school:" + school.toString());
return stringBuilder.toString();
}
}
为Student进行配置:

 
<bean id = "yoona" class = "com.sjf.bean.Student">
<constructor-arg name = "name" value = "yoona"/>
<constructor-arg name = "age" value = "24"/>
<constructor-arg name = "school" ref = "xidian"/>
</bean>
在这我们不能使用value属性为第二个构造参数赋值,因为School不是简单类型。取而代之的是,我们使用ref属性将ID为xidian的Bean引用传递给构造器。

你可能感兴趣的文章
项目实战-友盟项目介绍以及环境搭建
查看>>
2015年个人总结
查看>>
C#编程(六)------------枚举
查看>>
js点击下载跳转iOS或安卓
查看>>
高性能 Windows Socket 组件 HP-Socket v2.3.1-beta-2 发布
查看>>
零基础学python-2.24 一些经常使用函数
查看>>
hdu4762Cut the Cake(概率+大数操作(java)+C++高精度模板)
查看>>
Codeforces Round #256 (Div. 2) B. Suffix Structures
查看>>
栈3--后缀表达式
查看>>
JAVA interrupte中断线程的真正用途
查看>>
ZOJ 3316 Game 一般图最大匹配带花树
查看>>
linux后台运行jar程序
查看>>
Ubuntu 16.04安装Eclipse
查看>>
java中Object转String
查看>>
需求用例分析之备选流
查看>>
redis之如何配置jedisPool参数
查看>>
《系统架构师》——操作系统和硬件基础
查看>>
FTP下载工具
查看>>
oauth2-server-php for windows 的那些坑 (研究中...)
查看>>
文件名后缀详解
查看>>