除了使用XML配置外,还可以选择使用基于注解(annotation)的配置方式,其依赖于字节码来织入组件。
注解注入在XML注入之前完成,因此在XML配置中可以重载注解注入的属性。
通常,通过包含下列的XML配置来隐式的注册(包含context namespace):
<?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:annotation-config/>
</beans>
<context:annotation-config/>仅仅在同一个application context中查找bean的注解。这意味着,如果在DispatcherServlet的WebApplicationContext中使用<context:annotation-config/>,那么其只会在controller中检测@Autowired的bean,而不会在service中检测。
(<context:annotation-config/>会隐式的注册post-processors,包括AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, RequiredAnnotationBeanPostProcessor)
@Required
@Required注解应用在bean的属性setter方法中,
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Required
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
@Requried注解值检查属性是否已经设置而不会测试属性是否为空。该注解只能设置在 setter 方法上。
如果任何带有@Requried注解的属性未设置的话,将会抛出NullPointerException异常。
该注解实际会调用RequriedAnnotationBeanPostProcessor的调用。
@Autowired
@Autowired注解可以对类的成员变量,方法即构造函数进行标注,完成自动装配的工作。通过@Autowired来消除setter, getter方法。
Spring通过一个BeanProcessor对@Autowired进行解析,需要在容器配置中声明AutowiredAnnotationBeanPostProcessor Bean,在Spring3.0之后,只需要使用<context:annotation-config/>即可。
当Spring容器启动时,AutowiredAnnotationBeanPostProcessor将扫描Spring容器中所有Bean,当发现Bean中拥有@Autowired注解时就找到和其匹配(默认按类型匹配)的Bean,并注入到对应的地方中去。
@Autowired注解默认是按照类型装配注入的;如果想按照名称来装配注入,则需要结合@Qualifier一起使用。
@Qualifier
@Resource
Spring同样支持JSR-250的注解 @Resource ,该注解应用在类属性或者bean属性的setter方法上。
@Resource注解有一个 name 属性,Spring将这个值看作是要注入的bean的名称:
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource(name="myMovieFinder")
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
如果没有显式指定name属性,默认的name衍生自属性名称或者setter method方法名。如果注解在属性上,则使用属性名;如果注解在setter方法上,则使用bean属性名。例如,如下使用名为“movieFinder”的bean注入setter方法:
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
注解中的name属性被CommonAnnotationBeanPostProcessor解析成一个bean的名称。
@Resource注解默认是按照名称来装配注入的,只有当找不到与名称匹配的bean时才会按照类型来装配注入。
@PostConstruct, @PreDestroy
CommonAnnotationBeanPostProcessor不但识别@Resource注解,同时也可以识别JSR-250 生命周期注解。这些支持提供了initialization callback和destruction callback的另一种选择。