首先,装配bean可以理解为依赖关系的注入,spring ioc容器将指定bean对象创建好后传递给使用者的一个过程
基于xml装配
新手觉得这是理解较容易的一种装配方式
基于xml装配方式有两种方式:
从两种方式名字就可以看出,第一种是使用实例化对象的setter() 方法给对象赋值;第二种是使用构造方法实例化对象依次传参方式
1、设值注入(setter injection)
== 需要满足条件:==
A、必须提供一个默认的无参构造方法。(默认有)
B、必须为需要注入的属性提供对应的 setter 方法。
== xml文件中配置:==
配置每个bean元素下的子元素<property>设置参数的name 和参数值,例如:
//类里面关于参数的setter方法
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
<bean id="person1" class="com.mengma.assembly.Person">
<property name="name" value="zhangsan" />
<property name="age" value="20" />
</bean>
2、构造注入(Constructor Injection)
使用有参构造方法 实例化对象;
前提:
类里面声明有参构造方法的时候,也要设置一个无参构造方法
例如:
// 默认无参的构造方法
public Person() {
super();
}
// 有参的构造方法
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
xml配置文件里则设置:
<bean id="person2" class="com.mengma.assembly.Person">
<constructor-arg index="0" value="lisi" />
<constructor-arg index="1" value="21" />
</bean>
自动装配
1、基于Annotation装配
虽然基于xml的方式看起来很层次清晰,从xml文件里很容易就看出关系,但是如果要实例化的bean数量很多,那么全部放在xml里就会很多,从而变得难以维护。
1)@Component
可以使用此注解描述 Spring 中的 Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。
2)@Repository
用于将数据访问层(DAO层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
3)@Service
通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
eg:
@Resource 注解标注在 personService参数 上,这相当于在配置文件内编写 <property name="personService"ref="personService"/>
4)@Controller
通常作用在控制层(如 Struts2 的 Action),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
eg:
@Controller 注解标注 PersonAction 类,其写法相当于在配置文件中编写 <bean id="personAction"class="com.mengma.annotation.PersonAction"/>
5)@Autowired
用于对 Bean 的属性变量、属性的 Set 方法及构造函数进行标注,配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配。
6)@Resource
其作用与 Autowired 一样。其区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 实例名称进行装配 【Spring 将 name 属性解析为 Bean 实例名称,type 属性解析为 Bean 实例类型。如果指定 name 属性,则按实例名称进行装配;如果指定 type 属性,则按 Bean 类型进行装配。
】
7)@Qualifier
与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。
例如:
PersonService 接口的实现类 PersonServiceImpl :
@Service("personService")
public class PersonServiceImpl implements PersonService {
@Resource(name = "personDao")
private PersonDao personDao;
调用类:
@Controller("personAction")
public class PersonAction {
@Resource(name = "personService")
private PersonService personService;
此时,xml配置文件里可以只设置:
(component-scan :代表在指定package空间里扫描有注解的元素)
<context:component-scan base-package="com.mengma.annotation"/>
2、基于autowire装配
将一个bean主语其他bean的property 当中
== autowire 的五个属性值: ==
byName : 根据 Property 的 name 自动装配,如果一个 Bean 的 name 和另一个 Bean 中的 Property 的 name 相同,则自动装配这个 Bean 到 Property 中。
byType: 根据 Property 的数据类型(Type)自动装配,如果一个 Bean 的数据类型兼容另一个 Bean 中 Property 的数据类型,则自动装配。
constructor: 根据构造方法的参数的数据类型,进行 byType 模式的自动装配。
autodetect: 如果发现默认的构造方法,则用 constructor 模式,否则用 byType 模式。
no: 默认情况下,不使用自动装配,Bean 依赖必须通过 ref 元素定义。
== 基于 1中的部分java代码,可以修改xml文件,如下:==
(这一种是比较常用的方式)
<bean id="personDao" class="com.mengma.annotation.PersonDaoImpl" />
<bean id="personService" class="com.mengma.annotation.PersonServiceImpl"
autowire="byName" />
<bean id="personAction" class="com.mengma.annotation.PersonAction"
autowire="byName" />