我们在Spring配置文件中会习惯性的协商context:annotation-config.今天我们就来研究下这个配置的作用。

我们从http://www.springframework.org/schema/context/spring-context-3.0.xsd 中找到了Spring 3.0对这个标注的解释:

 
  
  1. <xsd:element name="annotation-config"> 
  2. <xsd:annotation> 
  3. <xsd:documentation> 
  4. <![CDATA[ 
  5. 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. 
  6. ]]> 
  7. </xsd:documentation> 
  8. </xsd:annotation> 
  9. </xsd:element> 

从这里可以看出它的描述是用来激活各种对于bean类的注解标注,这些标注可以是Spring的 (如@Required), 也可以是其他框架的,比如EJB3的,JPA的。

 

那么我们肯定要具体研究下这个注解如何影响这些注解的呢?

对于这个配置文件的java处理类是org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser 类

 
  
  1. public class AnnotationConfigBeanDefinitionParser implements BeanDefinitionParser { 
  2.  
  3.     public BeanDefinition parse(Element element, ParserContext parserContext) { 
  4.         Object source = parserContext.extractSource(element); 
  5.  
  6.         // Obtain bean definitions for all relevant BeanPostProcessors. 
  7.         Set<BeanDefinitionHolder> processorDefinitions = 
  8.                 AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source); 
  9.  
  10.         // Register component for the surrounding <context:annotation-config> element. 
  11.         CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source); 
  12.         parserContext.pushContainingComponent(compDefinition); 
  13.  
  14.         // Nest the concrete beans in the surrounding component. 
  15.         for (BeanDefinitionHolder processorDefinition : processorDefinitions) { 
  16.             parserContext.registerComponent(new BeanComponentDefinition(processorDefinition)); 
  17.         } 
  18.  
  19.         // Finally register the composite component. 
  20.         parserContext.popAndRegisterContainingComponent(); 
  21.  
  22.         return null
  23.     } 
  24.  

 

从这里我们可以很明显的看出来,在第04行,它会让ParseContext来提取这个配置元素。其中ParseContext是Spring框架中一个专门用于解析Spring的xml-based上下文配置文件的解析器。

然后第07-08行它会去读取所有Bean的用annotation标注的处理器,我们看下它到底分析了哪些标注,在AnnotationConfigUtils类中。

 
  
  1. public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( 
  2.             BeanDefinitionRegistry registry, Object source) { 
  3.  
  4.         Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4); 
  5.  
  6.         if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { 
  7.             RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); 
  8.             def.setSource(source); 
  9.             beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); 
  10.         } 
  11.  
  12.         if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { 
  13.             RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); 
  14.             def.setSource(source); 
  15.             beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); 
  16.         } 
  17.  
  18.         if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { 
  19.             RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); 
  20.             def.setSource(source); 
  21.             beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); 
  22.         } 
  23.  
  24.         // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. 
  25.         if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { 
  26.             RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); 
  27.             def.setSource(source); 
  28.             beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); 
  29.         } 
  30.  
  31.         // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor. 
  32.         if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { 
  33.             RootBeanDefinition def = new RootBeanDefinition(); 
  34.             try { 
  35.                 ClassLoader cl = AnnotationConfigUtils.class.getClassLoader(); 
  36.                 def.setBeanClass(cl.loadClass(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME)); 
  37.             } 
  38.             catch (ClassNotFoundException ex) { 
  39.                 throw new IllegalStateException( 
  40.                         "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); 
  41.             } 
  42.             def.setSource(source); 
  43.             beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); 
  44.         } 
  45.  
  46.         return beanDefs; 
  47.     } 

正如开始我们说的,它会除了处理Spring中的@Autowired,@Required,还会处理JSR-250,JPA等注解。

 

然后在第10-11行,它会吧所有用annotation标注的bean类向CompositeComponentDefinition注册。

然后在第14-15行,它会遍历这些处理器的定义,并且嵌套在具体bean上。