annotation-based configurations
1.概述:
-
- spring framework支持三种形式的configuration,xml-based configuration、annotion-based configuration、Java-based configuration。这三种方法各有优缺点,开发者可以根据实际需要选取某种方式编写配置代码来配置beans之间的依赖关系,也可以混合使用多种方式来编写配置代码。
- spring framework除了拥有自己定义的annotion之外,还支持其他标准所定义的annotion,如
-
- Spring 2.5 also added support for JSR-250 annotations such as
@PostConstruct
, and@PreDestroy
. - Spring 3.0 added support for JSR-330 (Dependency Injection for Java) annotations contained in the javax.inject package such as
@Inject
and@Named
.
- Spring 2.5 also added support for JSR-250 annotations such as
-
- 如果程序中同时使用了annotion-based configuration和xml-based configuration,那么xml中的配置信息会覆盖annotion中的配置信息。
2.spring framework所支持的注释
-
- spring framework自定义的annotion:
-
- @Required,指示某个属性必须被赋初始值,若没被赋初始值则抛出异常
- 该注解可以放在setter()或者init method上,使得实例化相应bean时,对应的属性必须被赋初始值
- example,
-
public class SimpleMovieLister { private MovieFinder movieFinder; @Required public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // ... }
- @Autowired自动初始化,给参数或者属性赋初始值
- 该注解可以放置在某个构造函数上或者被放置在setter函数上,也可以被放置在某个含参数的成员函数上,也可以直接修饰一个属性
- @Autowired是根据type匹配,并注册dependencies,有时候按照type匹配会匹配上多个bean实例,这时就需要@Autowired和@Primary、@Qulifier注解搭配使用
- @Autowired方式和@Resource注解都可以配置beans之间的依赖关系,前者按照type进行匹配,后者按照name进行匹配,通常我们建议使用@Resource注解配置依赖关系
-
public class MovieRecommender { private final CustomerPreferenceDao customerPreferenceDao; @Autowired public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) { this.customerPreferenceDao = customerPreferenceDao; } // ... }
-
public class SimpleMovieLister { private MovieFinder movieFinder; @Autowired public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // ... }
public class MovieRecommender { private MovieCatalog movieCatalog; private CustomerPreferenceDao customerPreferenceDao; @Autowired public void prepare(MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) { this.movieCatalog = movieCatalog; this.customerPreferenceDao = customerPreferenceDao; } // ... }
You can apply
@Autowired
to fields as well and even mix it with constructors:public class MovieRecommender { private final CustomerPreferenceDao customerPreferenceDao; @Autowired private MovieCatalog movieCatalog; @Autowired public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) { this.customerPreferenceDao = customerPreferenceDao; } // ... }
public class MovieRecommender { @Autowired private MovieCatalog[] movieCatalogs; // ... }
public class MovieRecommender { private Set<MovieCatalog> movieCatalogs; @Autowired public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) { this.movieCatalogs = movieCatalogs; } // ... }
-
public class MovieRecommender { private Map<String, MovieCatalog> movieCatalogs; @Autowired public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) { this.movieCatalogs = movieCatalogs; } // ... }
public class SimpleMovieLister { private MovieFinder movieFinder; @Autowired(required=false) public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // ... }
-
@Order
or standard@Priority
annotation-
Your beans can implement the
org.springframework.core.Ordered
interface or either use the@Order
or standard@Priority
annotation if you want items in the array or list to be sorted into a specific order.
-
-
@Primary
-
使用该注解微调@autowired注解,@Autowired注解默认情况下会使IOC容器按照type类型注入dependencies,但是按照type进行匹配的话有可能会有多个候选方案都满足匹配条件,这会抛出异常,所以使用@Primary对@Autowired进行更精确的控制,使得有多个bean实例都满足要求时,只选用使用@Primary 标注的实例被用于注册到其他的bean实例中
-
@Configuration public class MovieConfiguration { @Bean @Primary public MovieCatalog firstMovieCatalog() { ... } @Bean public MovieCatalog secondMovieCatalog() { ... } // ... }
With such configuration, the following
MovieRecommender
will be autowired with thefirstMovieCatalog
.public class MovieRecommender { @Autowired private MovieCatalog movieCatalog; // ... }
上述配置和下面的xml-based configuration等效:
<?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/> <bean class="example.SimpleMovieCatalog" primary="true"> <!-- inject any dependencies required by this bean --> </bean> <bean class="example.SimpleMovieCatalog"> <!-- inject any dependencies required by this bean --> </bean> <bean id="movieRecommender" class="example.MovieRecommender"/> </beans>
-
-
@Qualifier
- 和@Primary注解一样,这个注解也是用于有多个bean实例符合备选条件的情况,当有多个bean实例符合备选条件时,IOC容器会不知道应该选择哪个实例作为依赖注入其他bean实例,这时就需要使用@Qulifier注解来告诉IOC容器应该选择哪个具体的bean实例作为被注入的bean实例
-
public class MovieRecommender { @Autowired @Qualifier("main") private MovieCatalog movieCatalog; // ... }
The
@Qualifier
annotation can also be specified on individual constructor arguments or method parameters:public class MovieRecommender { private MovieCatalog movieCatalog; private CustomerPreferenceDao customerPreferenceDao; @Autowired public void prepare(@Qualifier("main")MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) { this.movieCatalog = movieCatalog; this.customerPreferenceDao = customerPreferenceDao; } // ... }
<?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/> <bean class="example.SimpleMovieCatalog"> <qualifier value="main"/> <!-- inject any dependencies required by this bean --> </bean> <bean class="example.SimpleMovieCatalog"> <qualifier value="action"/> <!-- inject any dependencies required by this bean --> </bean> <bean id="movieRecommender" class="example.MovieRecommender"/> </beans>
-
@Resource
- @Required,指示某个属性必须被赋初始值,若没被赋初始值则抛出异常
-
- spring framework自定义的annotion:
3.如何使用spring framework中的annotion-based configuration
-
- step1,首先弄懂spring framework中支持哪些注解,如@required、@autowired。。。
- step2,在spring 的IOC容器中声明相应的bean,以使得IOC容器可以识别这些annotion
- 概述,可以有三种方法声明annotion相关的bean,从而使得IOC容器可以识别这些annotion
- 方法一,直接声明相应注解对应的bean,如若要使用 @Required注解,就必须声明RequiredAnnotationBeanPostProcessor的Bean
-
- AutowiredAnnotationBeanPostProcessor,@Autowired
- CommonAnnotationBeanPostProcessor,@Resource、@PostConstruct、@PreDestroy
- PersistenceAnnotationBeanPostProcessor,@PersistenceContext
- RequiredAnnotationBeanPostProcessor,@Required
- 。。。
-
- 方法二,直接通过<context:annotation-config/>来将上述所有注解相关的XxxAnnotionBeanPostProcessor都包含进对应的IOC容器,使得该容器可以识别所有的注解
- 方法三,可以直接通过<context:component-scan base-package="pack.pack"/>使得IOC容器可以识别上述所有注解
- 更多 解释参见博客:如何使得spring framework相关的注解annotion生效
- 具体操作:spring-configuration.xml
<?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"> <!--在spring的配置文件(即spring的IOC容器)中添加以下配置信息,使得spring IOC容器可以识别spring framework中各个注解是什么意思 下面的一行代码实际上为该IOC容器引入了AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, 以及 the aforementioned RequiredAnnotationBeanPostProcessor,这样一来该IOC容器就可以识别@Autowired、(@Resource、@PostConstruct、@PreDestroy)、@PersistenceContext、@Required等注解了--> <context:annotation-config/> </beans>
-
step3,明确上述代码虽然配置IOC容器使得该IOC容器能够识别相关注解,但是这个识别是有一定范围的:即该配置使得该IOC容器只会扫描该容器范围之内的bean的annotion信息,范围之外的annotion信息它是不会理会的。