1. spring自己定义的注释@Autowired, @Qualifier
当注释用在bean的属性上时,可以省略bean中的setter/getter方法,而且在<bean>定义中也不需要再指定property属性了,容器会自动装配。
@Autowired默认是byType的,当采用该标记时,如果发现没有匹配的bean可用,或者有多于一个的bean可用,则spring容器在启动的时候会报BeanCreationException异常。例如有如下bean,
public class Boss { @Autowired private Office office; @Autowired private Car car; }
当使用@Autowired注释这两个属性的时候,如果在容器中没有Office/Car bean的定义,或者有多于一个的Office/Car bean的定义,spring容器在启动初始化Boss bean的时候就会报BeanCreationException。
为了解决这个问题,spring提供了@Qualifier注释。当结合使用了@Qualifier注释时,自动注入的策略就由byType变为byName了,如下:
public class Boss { @Autowired private Office office; @Autowired @Qualifier("newCar") private Car car; }
这时如果有多个Car bean的定义,容器只会使用id为"newCar"的Car bean对Boss进行装配。
为了使用@Autowired注释,需要配置一个BeanPostProcessor对@Autowired进行解析,这个BeanPostProcessor就是AutowiredAnnotationBeanPostProcessor,因此需要添加如下配置:
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
2. JSR-250规范定义的注释@Resource, @PostConstruct, @PreDestroy
@Resource和@Autowired一样,不过默认方式是byName, @Autowired默认是byType的。上面的Boss bean可以采用@Resource如下定义:
public class Boss { @Resource private Office office; @Resource(name="newCar") private Car car; }
指定容器在bean的初始化之后或者销毁之前应该执行的方法可以有如下三种方式:
- 实现InitializingBean/DisposableBean接口中的afterPropertiesSet()/destroy()方法
- 通过bean定义文件的init-method/destroy-method指定方法
- 通过@PostConstruct和@PreDestroy来注释相应的方法(通过该注释可以标注多个init/destroy方法)
为了使用这些JSR-250定义的注释,需要在容器中注册一个BeanPostProcessor,如下:
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
3. 上面提到的两个BeanPostProcessor也可以通过如下配置来实现在容器中的注册,而不需要专门的两个bean定义。
<context:annotation-config/>
<context:annotation-config/>将隐式地像spring注册AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, equiredAnnotationBeanPostProcessor这4个BeanPostProcessor。
在配置文件中使用 context 命名空间之前,必须在 <beans> 元素中声明 context 命名空间:
xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context/spring-context-2.5.xsd"
4. @Component
使用@Component来注释一个类,效果上相当于将该类注册到spring容器中。@Component带有一个可选的参数,用于指定bean的名称,如@Component("boss"),则可以通过"boss"从容器中取得Boss类的实例。
为了使用@Component注释,需要在<beans>中引入如下配置:
<context:component-scan base-package="...">
spring会自动扫描base-package指定的包及子包下面所有标记了@Component的类并自动注册到容器中。
使用了上面的配置之后,就不必再有<context:annotation-config/>配置了,因为<context:component-scan>会自动隐式地注册AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor。
<context:component-scan>还可以指定要扫描的包、类的filter,如下:
<context:component-scan base-package="..."> <context:include-filter type="regex" expression="..."/> <context:exclude-filter type="aspectj"expression="..."/> </context:component-scan>
默认地,@Component标注的bean都是singleton的,可以通过@Scope("prototype")来改变,如下:
@Component("boss") @Scope("prototype") public class Boss { // ... }
5. Spring MVC中的annotation