public class Student {
private String sname;
private Integer sage;
private List<Course> courses;
private Teacher classTeacher;
}
public class Course {
private String courseName;
}
public class Teacher {
private String tname;
}
public class Student {
private String sname;
private Integer sage;
private List<Course> courses;
private Teacher classTeacher;
public void setSname(String sname) {
this.sname = sname;
}
public void setSage(Integer sage) {
this.sage = sage;
}
public void setCourses(List<Course> courses) {
this.courses = courses;
}
public void setClassTeacher(Teacher classTeacher) {
this.classTeacher = classTeacher;
}
@Override
public String toString() {
return "Student{" +
"sname='" + sname + '\'' +
", sage=" + sage +
", courses=" + courses +
", classTeacher=" + classTeacher +
'}';
}
}
类Course 和Teacher 按照上述代码添加setter方法,在此不再赘述。
2. 在resources目录下添加spring配置文件spring-assemble-set.xml,代码如下所示。
<beans>
<bean id="teacher" class="com.bjwl.service.setter.Teacher">
<property name="tname" value="李老师">property>
bean>
<bean id="student" class="com.bjwl.service.setter.Student">
<property name="sname" value="张三">property>
<property name="sage" value="18">property>
<property name="classTeacher" ref="teacher">property>
<property name="courses">
<list value-type="com.bjwl.service.setter.Course">
<bean class="com.bjwl.service.setter.Course">
<property name="courseName" value="数据结构">property>
bean>
<bean class="com.bjwl.service.setter.Course">
<property name="courseName" value="数据库原理">property>
bean>
list>
property>
bean>
beans>
在配置文件中property对应对象的属性, value对应简单数据类型的属性值;当属性值是由spring管理的对象时使用ref引用属性值,当使用list、map等类型时,需要进一步描述数据类型等信息。
public class AssembleTest {
@Test
public void setterTest(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring-assemble-set.xml");
Student student = (Student)context.getBean("student");
System.out.println(student.toString());
}
}
public class Student {
private String sname;
private Integer sage;
private List<Course> courses;
private Teacher classTeacher;
public Student(String sname, Integer sage, List<Course> courses, Teacher classTeacher) {
this.sname = sname;
this.sage = sage;
this.courses = courses;
this.classTeacher = classTeacher;
}
@Override
public String toString() {
return "Student{" +
"sname='" + sname + '\'' +
", sage=" + sage +
", courses=" + courses +
", classTeacher=" + classTeacher +
'}';
}
}
类Course 和Teacher 按照上述代码添加setter方法,在此不再赘述。
2. 在resources目录下添加spring配置文件spring-constructor.xml,代码如下所示。
<beans>
<bean id="teacher" class="com.bjwl.service.constructor.Teacher">
<constructor-arg index="0" value="张三">constructor-arg>
bean>
<bean id="student" class="com.bjwl.service.constructor.Student">
<constructor-arg index="0" value="张三">constructor-arg>
<constructor-arg index="1" value="18">constructor-arg>
<constructor-arg index="3" ref="teacher">constructor-arg>
<constructor-arg index="2">
<list value-type="com.bjwl.service.constructor.Course">
<bean class="com.bjwl.service.constructor.Course">
<constructor-arg name="courseName" value="数据结构">constructor-arg>
bean>
<bean class="com.bjwl.service.constructor.Course">
<constructor-arg name="courseName" value="数据库原理">constructor-arg>
bean>
list>
constructor-arg >
bean>
代码中constructor-arg标签为构造注入标签,constructor-arg中index是参数的索引,value对应简单数据类型的属性值;当属性值是由spring管理的对象时使用ref引用属性值。注意:在正式开发中通常使用constructor-arg标签中使用name属性,而不是index属性,因为name对应构造函数的行参名,更加准确。
public class AssembleTest {
@Test
public void constructorTest(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring-constructor.xml");
Student student = context.getBean("student",Student.class);
System.out.println(student.toString());
}
}
@Component
public class Student {
@Value("张三")
private String sname;
@Value("18")
private Integer sage;
@Value("#{courses}")
private List<Course> courses;
@Autowired
private Teacher classTeacher;
}
@Component
public class Teacher {
@Value("李老师")
private String tname;
}
@Component
public class Course {
public void setCourseName(String courseName) {
this.courseName = courseName;
}
private String courseName;
}
代码中在类上添加的注解符@Component ,代表这个类创建的对象交给spring进行管理,在属性上的@Value注解符,代表简单数据类型属性注入,@Autowired代表对象的注入。对于list、map的注入还要借助xml完成,如:课程集合的注入。
注意:对象注入时,使用@Autowired注解符是spring提供的,注入依据数据类型(byType),如:classTeacher属性注入,是spring在对象池中寻找类型为Teacher的对象,然后进行匹配,如果系统中存在两个或两个以上类型为Teacher的对象,需要借助另外一个注解符@Qualifier完成;另外JDK还提供了一个注解符@Resource,也可以完成依赖注入,注入依据对象的名称(byName),上例中需要在对象池中寻找名称为classTeacher的对象进行注入。
<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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<context:annotation-config />
<context:component-scan base-package="com.bjwl.service.annotation" />
<util:list id="courses">
<bean id="course1" class="com.bjwl.service.annotation.Course" >
<property name="courseName" value="数据结构">property>
bean>
<bean id="course2" class="com.bjwl.service.annotation.Course" >
<property name="courseName" value="数据库原理">property>
bean>
util:list>
beans>
代码的第3、7、8行引入context的头部文件,第12行开启注解注解Bean装配,第13行声明组件扫描位置
3. 编写测试程序,在测试类中增加AnnotationTest 方法,代码如下所示。
public void setterTest(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring-annotation.xml");
Student student = (Student)context.getBean("student");
System.out.println(student.toString());
}
public class Student {
@Value("李四")
private String sname;
@Value("18")
private Integer sage;
private Teacher classTeacher;
public void setSname(String sname) {
this.sname = sname;
}
public void setSage(Integer sage) {
this.sage = sage;
}
public void setClassTeacher(Teacher classTeacher) {
this.classTeacher = classTeacher;
}
@Override
public String toString() {
//省略
}
}
@Component("classTeacher")
public class Teacher {
@Override
public String toString() {
//省略
}
@Value("zhangsan")
private String tname;
}
<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.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName">
<context:annotation-config />
<context:component-scan base-package="com.bjwl.service.auto" />
beans>
代码第7行beans 指定default-autowire属性的值为byName,通过属性的名称实现自动装配,此时要求student的classTeacher属性名必须 bean所对应的名称完全一致,default-autowire属性值也可以是为byType,通过属性的类型实现自动装配。此种装配方式简单,但是缺乏灵活度,开发时几乎不用。
public class AutoTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring-auto.xml");
Student student = context.getBean("student", Student.class);
System.out.println(student.toString());
}
}
本节主要介绍了bean的装配实现过程,通常对于简单数据类型数据初始主要在获得对象后,使用setter方法完成,所谓的装配主要是复杂数据类型的依赖注入。Bean的装配可以基于xml配置、注解、自动化装配三种方式,当前主流的使用基于注解的装配,基于xml配置辅助,自动化装配技术几乎不用。在基于注解的配置中,特别注意注解符@Autowired和@Resource匹配规则及使用byType时,@Qualifier使用场景和原因。