Spring Bean的装配方式 在 Spring 中,对象无需自己查找或创建与其关联的其他对象。而是由容器负责把需要相互协作的对象引用赋予各个对象。创建应用对象之间的协作关系的行为通常称为装配,这也是依赖注入的本质。
1.基于 XML 的 Bean 装配简介 Spring 基于 XML 的装配通常有两种实现方式,一是设值注入,二是构造注入。
在 Spring 实例化 Bean 的过程中,首先会调用默认的构造方法实例化 Bean 对象,然后通过 Java 的反射机制调用 setXxx() 方法进行属性的注入。因此,设值注入要求一个 Bean 的对应类必须满足两个要求:
一是提供一个无参构造方法;二是为需要注入的属性提供对应的 setter 方法。
使用设值注入时,在配置文件 applicationContext.xml
中需要使用 bean 元素的子元素 property
为每个属性注入值。
使用构造注入时,在配置文件中,需要使用 constructor-arg
标签定义构造方法的参数,可以使用其 value
属性设置该参数的值。
任务代码 Person.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package educoder;public class Person { private String name; private String sex; public Person () { } public Person (String name,String sex) { this .name=name; this .sex=sex; } @Override public String toString () { return "Person{" + "name='" + name + '\'' + ", sex='" + sex + '\'' + '}' ; } public String getSex () { return sex; } public void setSex (String sex) { this .sex=sex; } public String getName () { return name; } public void setName (String name) { this .name=name; } }
applicationContext.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?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:p ="http://www.springframework.org/schema/p" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd" > <bean id ="person1" class ="educoder.Person" > <property name ="name" value ="张三" /> <property name ="sex" value ="男" /> </bean > <bean id ="person2" class ="educoder.Person" > <constructor-arg index ="0" value ="李四" /> <constructor-arg index ="1" value ="女" /> </bean > </beans >
2.基于注解的Bean装配 在 Spring 中,尽管使用 XML 配置文件可以实现 Bean 的装配工作,但如果配置文件中 Bean 的数量较多,会导致 XML 配置文件过于臃肿,从而给维护和升级带来一定的困难。因此,基于注解的 Bean 装配应运而生。
常用的注解
注解
说明
@Component 注解
该注解可以作用在任何层次(Dao 层、Controller 层等),它用来描述 Spring 中的 Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),使用时只需将该注解标注在相应类上。
@Repository 注解
该注解通常作用在数据访问层(DAO 层),用来标识 Spring 中的 Bean,其功能与 @Component 相同。
@Service 注解
该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Controller 注解
该注解通常作用在控制层,用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Autowired 注解
用于对 Bean 的属性变量、属性的 Set 方法及构造函数进行标注,配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配。
@Resource 注解
其作用与 Autowired 一样。其区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 实例名称进行装配,该注解有两个重要属性:name 和 type。Spring 将 name 属性解析为 Bean 实例名称,type 属性解析为 Bean 实例类型。如果指定 name 属性,则按实例名称进行装配;如果指定 type 属性,则按 Bean 类型进行装配。如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常。
任务代码 StudentDaoImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.educoder.springtest;import org.springframework.stereotype.Repository;@Repository("studentDao") public class StudentDaoImpl implements StudentDao { @Override public void showTables () { System.out.println("执行Dao层的showTables()方法" ); } }
StudentServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package com.educoder.springtest;import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service("studentService") public class StudentServiceImpl implements StudentService { @Resource(name = "studentDao") private StudentDao studentDao; public StudentDao getStudentDao () { return studentDao; } public void setStudentDao (StudentDao studentDao) { this .studentDao=studentDao; } @Override public void toTime () { studentDao.showTables(); System.out.println("执行Service层的toTime()方法" ); } }
StudentAction.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package com.educoder.springtest;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controller("studentAction") public class StudentAction { @Resource(name = "studentService") private StudentService studentService; public StudentService getStudentService () { return studentService; } public void setStudentService (StudentService studentService ) { this .studentService=studentService; } public void show () { studentService.toTime(); System.out.println("执行Action层的show()方法" ); } }
3.自动装配 Bean 自动装配就是指 Spring 容器可以自动装配相互协作的 Bean 之间的关联关系,将一个 Bean 注入其他 Bean 的 Property 中。
Bean 元素的 autowire 属性
如果要使用自动装配,需要配置 Bean 元素的 autowire 属性。
名称
说明
byName
根据 Property 的 name 自动装配,如果一个 Bean 的 name 和另一个 Bean 中的 Property 的 name 相同,则自动装配这个 Bean 到 Property 中。当一个 Bean 节点带有 autowire 的属性时,将查找其类中所有的 set 方法名,获得将 set 去掉并且首字母小写的字符串,然后去 spring 容器中寻找是否有此字符串名称 id 的对象。如果有,就取出注入;如果没有,就报空指针异常。
byType
根据 Property 的数据类型(Type)自动装配,如果一个 Bean 的数据类型兼容另一个 Bean 中 Property 的数据类型,则自动装配。
constructor
根据构造方法的参数的数据类型,进行 byType 模式的自动装配。
autodetect
如果发现默认的构造方法,则用 constructor 模式,否则用 byType 模式。
no
默认情况下,不使用自动装配,Bean 依赖必须通过 ref 元素定义。
任务代码 先把在第2关StudentDaoImpl.java
、StudentServiceImpl.java
、StudentAction.java
中的添加的注解去掉或者注释。
applicationContext.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?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:aop ="http://www.springframework.org/schema/aop" xmlns:p ="http://www.springframework.org/schema/p" xmlns:tx ="http://www.springframework.org/schema/tx" xmlns:context ="http://www.springframework.org/schema/context" xsi:schemaLocation =" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" > <bean id ="studentDao" class ="com.educoder.springtest.StudentDaoImpl" /> <bean id ="studentService" class ="com.educoder.springtest.StudentServiceImpl" autowire ="byName" /> <bean id ="studentAction" class ="com.educoder.springtest.StudentAction" autowire ="byName" /> </beans >
实训地址:头歌编程