使用注解装配bean
使用@Autowired注解
从Spring2.5开始,最有趣的一种装配Spring Bean的方式是使用注解自动装配Bean的属性。
Spring默认禁用注解装配,最简单的启用方式是使用Spring的context命名空间配置中的<context:annotation-config>元素,如下所示:
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<!-- bean declarations here -->
</beans>
继续上一节的例子,在xml文件中定义两个bean:falchion bean和guanyu bean,为了实现@Autowired自动装配,在GuanYu类中的setWeapon()方法前添加了@Autowired注解,如下:
GuanYu.java:
package com.moonlit.myspring;
import org.springframework.beans.factory.annotation.Autowired;
public class GuanYu implements Hero {
@Autowired
private Weapon weapon;
public void perform() {
System.out.println("Guan Yu pick up his weapon.");
weapon.attack();
}
public Weapon getWeapon() {
return weapon;
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
}
通过基于注解的方式,可以不用在xml文件中为guanyu bean添加autowire属性了。
spring-idol内部的代码:
<context:annotation-config />
<bean id="falchion" class="com.moonlit.myspring.Falchion" />
<bean id="guanyu" class="com.moonlit.myspring.GuanYu" />
@Autowired注解存在一个限制:
匹配多个Bean
限定歧义性的依赖
有可能存在多个bean满足装配条件,比如,这里,falchion bean和halberd bean都满足装配到guanyu bean的weapon属性中的条件。此时如果只是用@Autowired注解的话就会出问题,才@Autowired注解下添加@Qualifier注解如下:
@Autowired
@Qualifier("falchion")
private Weapon weapon;
就会将falchion bean装入到weapon中。
如上所示,@Qualifier注解将尝试注入ID为falchion的Bean。
除了通过Bean的ID来限定,也可以给Bean添加一个qualifier属性,通过这个qualifier属性来获得限定,如:
给halberd bean添加一个qualifier,值为"weaponOfGuanYu":
<bean id="halberd" class="com.moonlit.myspring.Halberd">
<qualifier value="weaponOfGuanYu" />
</bean>
然后对GuanYu类weapon类的注解如下:
@Autowired
@Qualifier("weaponOfGuanYu")
private Weapon weapon;
输出如下:
Guan Yu pick up his weapon.
halberd is attacking!!!
可以看出,@qualifier降低了@Autowired的匹配范围,最终筛选得到了halberd bean装入weapon属性。
这里的<qualifier>元素限定了方天画戟(halberd)Bean是关羽使用的武器(weaponOgGuanYu)。除了可以在XML中指定qualifier,还可以使用Qualifier类来标注Halberd类:
package com.moonlit.myspring;
import org.springframework.beans.factory.annotation.Qualifier;
@Qualifier("weaponOfGuanYu")
public class Halberd implements Weapon {
public void attack() {
System.out.println("halberd is attacking!!!");
}
}
程序运行将得到相同的结果。
即使<context:annotation-config>有助于完全消除Spring配置文件中的元素,但是还是不能完全消除,仍然需要使用<bean>元素显示定义Bean。因此<context:component-scan>元素出现了,它除了完成<context:annotation-config>一样的工作,还允许Spring自动检测Bean和定义Bean。这就意味着不使用<bean>元素,Spring应用中的大多数(或者所有)Bean都能够自动实现定义和装配。
自动检测
为了配置Spring自动检测,需要使用<context:component-scan>元素来代替<context:annotation-config>元素:
<?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: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 http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.moonlit.myspring">
</context:component-scan>
</beans>
<context:component-scan>元素会扫描指定的包以及所有子包,并查找出能够自动注册为Spring Bean的类。base-package属性标示了<context:component-scan>元素所扫描的包。
为自动检测标注Bean
默认情况下,<context:component-scan>查找使用构造型(stereotype)注解所标注的类,这些特殊的注解如下:
类型 说明
@component 通用的构造型注解,标示该类为Spring 组件。
@Controller 标识将该类定义为Spring MVC controller。
@Repository 标识将该类定义为数据仓库(例如:Dao层)。
@Service 标识将该类定义为服务(例如:Service层)。
效果相同,都是告诉Spring框架在启动时就初始化对象,但是语义不同
@component("guanyu")
ApplicationContext applicationContext
= new ClassPathXmlApplicationContext("spring.xml");
Hero hero = (Hero)applicationContext.getBean("guanyu");
hero.perform();
网友评论