天天看點

關于Spring 中的context:annotation-config

 我們在Spring配置檔案中會習慣性的協商context:annotation-config.今天我們就來研究下這個配置的作用。

<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); 

            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); 

        if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { 

            RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); 

            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); 

            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); 

            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上。

本文轉自 charles_wang888 51CTO部落格,原文連結:http://blog.51cto.com/supercharles888/1159402,如需轉載請自行聯系原作者