我们在Spring配置文件中会习惯性的协商context:annotation-config.今天我们就来研究下这个配置的作用。
我们从 中找到了Spring 3.0对这个标注的解释:
- <xsd:element name="annotation-config">
- <xsd:annotation>
- <xsd:documentation>
- <![CDATA[
- Activates various annotations to be detected in bean classes: Spring's @Required and @Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available), JAX-WS's @WebServiceRef (if available), EJB3's @EJB (if available), and JPA's @PersistenceContext and @PersistenceUnit (if available). Alternatively, you may choose to activate the individual BeanPostProcessors for those annotations. Note: This tag does not activate processing of Spring's @Transactional or EJB3's @TransactionAttribute annotation. Consider the use of the <tx:annotation-driven> tag for that purpose.
- ]]>
- </xsd:documentation>
- </xsd:annotation>
- </xsd:element>
从这里可以看出它的描述是用来激活各种对于bean类的注解标注,这些标注可以是Spring的 (如@Required), 也可以是其他框架的,比如EJB3的,JPA的。
那么我们肯定要具体研究下这个注解如何影响这些注解的呢?
对于这个配置文件的java处理类是org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser 类
- public class AnnotationConfigBeanDefinitionParser implements BeanDefinitionParser {
- public BeanDefinition parse(Element element, ParserContext parserContext) {
- Object source = parserContext.extractSource(element);
- // Obtain bean definitions for all relevant BeanPostProcessors.
- Set<BeanDefinitionHolder> processorDefinitions =
- AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source);
- // Register component for the surrounding <context:annotation-config> element.
- CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
- parserContext.pushContainingComponent(compDefinition);
- // Nest the concrete beans in the surrounding component.
- for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
- parserContext.registerComponent(new BeanComponentDefinition(processorDefinition));
- }
- // Finally register the composite component.
- parserContext.popAndRegisterContainingComponent();
- return null;
- }
- }
从这里我们可以很明显的看出来,在第04行,它会让ParseContext来提取这个配置元素。其中ParseContext是Spring框架中一个专门用于解析Spring的xml-based上下文配置文件的解析器。
然后第07-08行它会去读取所有Bean的用annotation标注的处理器,我们看下它到底分析了哪些标注,在AnnotationConfigUtils类中。
- public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
- BeanDefinitionRegistry registry, Object source) {
- Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
- if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
- if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
- if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- RootBeanDefinition def = new RootBeanDefinition();
- try {
- ClassLoader cl = AnnotationConfigUtils.class.getClassLoader();
- def.setBeanClass(cl.loadClass(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME));
- }
- catch (ClassNotFoundException ex) {
- throw new IllegalStateException(
- "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
- }
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- return beanDefs;
- }
正如开始我们说的,它会除了处理Spring中的@Autowired,@Required,还会处理JSR-250,JPA等注解。
然后在第10-11行,它会吧所有用annotation标注的bean类向CompositeComponentDefinition注册。
然后在第14-15行,它会遍历这些处理器的定义,并且嵌套在具体bean上。