zoukankan      html  css  js  c++  java
  • springMVC之<context:annotation-config />标签

    springMVC的配置文件中经常见到<context:annotation-config/>,那么这句话的作用到底是什么呢?

    现在的注解非常方便,但是系统如何才能识别注解呢,这就需要相应的处理程序了,springMVC使用AnnotationBeanPostProcessor让系统能够识别相应的注解

    例如:如果你想使用Autowired注解,那么必须先在spring容器中声明AutoWiredAnnotationBeanPostProccessor的实例,如要使用@Required注解就必须先声明RequiredAnnotationBeanPostProccessor,一般的方法是在配置文件挨个定义:

    //@AutoWired注解处理器
    <
    bean class="org.springframework.beans.factory.annotation. AutowiredAnnotationBeanPostProcessor "/> //@Required注解处理器 <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>

    然而对于这些常见的注解,每次显示定义很麻烦,所以springMVC给我们提供了隐式定义的方法,即<context:annotation-config/>标签。

    下面看看<context:annotation-config/>标签注册过程及注册了哪些实例到容器

    首先找到实例定义接口BeanDefinitionParser

    public class AnnotationConfigBeanDefinitionParser implements BeanDefinitionParser {
        public BeanDefinition parse(Element element, ParserContext parserContext) {
            Object source = parserContext.extractSource(element);
         //得到一个set集合,此集合中就是各个注解的处理器(AnnotationBeanPostProcessor)和一些事件监听处理器
            Set processorDefinitions = AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source);
    
            CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
            parserContext.pushContainingComponent(compDefinition);
    
            for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
                parserContext.registerComponent(new BeanComponentDefinition(processorDefinition));
            }
    
            parserContext.popAndRegisterContainingComponent();
    
            return null;
        }
    }

    查看registerAnnotationConfigProcessors方法

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
                BeanDefinitionRegistry registry, Object source) {
            DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
            if (beanFactory != null) {
                if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                    beanFactory
                            .setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
                }
                if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                    beanFactory
                            .setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
                }
            }
    
            Set beanDefs = new LinkedHashSet(4);
    
            if (!(registry
                    .containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor"))) {
                RootBeanDefinition def = new RootBeanDefinition(
                        ConfigurationClassPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(
                        registry,
                        def,
                        "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
            }
         //Autowired注解处理器
            if (!(registry
                    .containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor"))) {
                RootBeanDefinition def = new RootBeanDefinition(
                        AutowiredAnnotationBeanPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def,
                        "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));
            }
         //Required注解处理器  
            if (!(registry
                    .containsBeanDefinition("org.springframework.context.annotation.internalRequiredAnnotationProcessor"))) {
                RootBeanDefinition def = new RootBeanDefinition(
                        RequiredAnnotationBeanPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def,
                        "org.springframework.context.annotation.internalRequiredAnnotationProcessor"));
            }
         //@Resource、@PostConstruct、@PreDestroy等注解处理器
            if ((jsr250Present)
                    && (!(registry
                            .containsBeanDefinition("org.springframework.context.annotation.internalCommonAnnotationProcessor")))) {
                RootBeanDefinition def = new RootBeanDefinition(
                        CommonAnnotationBeanPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def,
                        "org.springframework.context.annotation.internalCommonAnnotationProcessor"));
            }
    
            if ((jpaPresent)
                    && (!(registry
                            .containsBeanDefinition("org.springframework.context.annotation.internalPersistenceAnnotationProcessor")))) {
                RootBeanDefinition def = new RootBeanDefinition();
                try {
                    def.setBeanClass(ClassUtils
                            .forName(
                                    "org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor",
                                    AnnotationConfigUtils.class.getClassLoader()));
                } catch (ClassNotFoundException ex) {
                    throw new IllegalStateException(
                            "Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor",
                            ex);
                }
    
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def,
                        "org.springframework.context.annotation.internalPersistenceAnnotationProcessor"));
            }
    
            if (!(registry
                    .containsBeanDefinition("org.springframework.context.event.internalEventListenerProcessor"))) {
                RootBeanDefinition def = new RootBeanDefinition(
                        EventListenerMethodProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def,
                        "org.springframework.context.event.internalEventListenerProcessor"));
            }
            if (!(registry
                    .containsBeanDefinition("org.springframework.context.event.internalEventListenerFactory"))) {
                RootBeanDefinition def = new RootBeanDefinition(
                        DefaultEventListenerFactory.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def,
                        "org.springframework.context.event.internalEventListenerFactory"));
            }
    
            return beanDefs;
        }

    for循环逐个注册实例,registerComponent方法

    public void registerComponent(ComponentDefinition component) {
            CompositeComponentDefinition containingComponent = getContainingComponent();
            if (containingComponent != null) {
                containingComponent.addNestedComponent(component);
            } else
                this.readerContext.fireComponentRegistered(component);
        }

    addNestedComponent方法(省略部分代码)

    public class CompositeComponentDefinition extends AbstractComponentDefinition {

      private final List<ComponentDefinition> nestedComponents = new LinkedList();
      
    public void addNestedComponent(ComponentDefinition component) { Assert.notNull(component, "ComponentDefinition must not be null"); this.nestedComponents.add(component); }
    }

    可看到,最终实例存到了一个链表中,整个bean注册过程基本完成。 

    不过,该标签的功能被

    <context:component-scan base-package=”**.**”/>

    标签所包含,及扫描时也会注入上述实例,所以,在配置了自动扫描包配置之后,本标签可省略不配置。

  • 相关阅读:
    Spring Boot2 系列教程(十三)Spring Boot 中的全局异常处理
    Spring Boot2 系列教程(十二)@ControllerAdvice 的三种使用场景
    Spring Boot2 系列教程(十一)Spring Boot 中的静态资源配置
    Spring Boot2 系列教程(十)Spring Boot 整合 Freemarker
    Python pass 语句
    Python continue 语句
    Python break 语句
    Python 循环嵌套
    Python for 循环语句
    小程序开发中的六大问题难点
  • 原文地址:https://www.cnblogs.com/xiao-tao/p/6225133.html
Copyright © 2011-2022 走看看