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=”**.**”/>

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

springMVC之<context:annotation-config />标签的更多相关文章

  1. Mingyang.net:org.springframework.context.annotation.ConflictingBeanDefinitionException

    org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean ...

  2. 【原创】大叔经验分享(16)Context namespace element 'component-scan' and its parser class [org.springframework.context.annotation.ComponentScanBeanDefinitionParser] are only available on JDK 1.5 and higher

    今天尝试运行一个古老的工程,配置好之后编译通过,结果运行时报错: org.springframework.beans.factory.BeanDefinitionStoreException: Une ...

  3. spring 2.5.6 错误:Context namespace element 'component-scan' and its parser class [org.springframework.context.annotation.ComponentScanBeanDefinitionParser] are only available on JDK 1.5 and higher

    在运行一个第三方公司交付的项目的时候, 出现: Caused by: java.lang.IllegalStateException: Context namespace element 'annot ...

  4. context、config

    Tomcat启动时已经创建了context,并使用它读取了web.xml中的参数,后台可以从context里获取参数 后台获取参数代码: ServletContext context = getSer ...

  5. Context namespace element 'annotation-config' and its parser class [org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser]

    严重: Exception sending context initialized event to listener instance of class org.springframework.we ...

  6. class [org.springframework.context.annotation.ComponentScanBeanDefinitionParser] are only available on JDK 1.5 and higher

    在搭建SSM项目时报了以下的错误: 06-Oct-2019 11:55:52.109 信息 [RMI TCP Connection(5)-127.0.0.1] org.apache.catalina. ...

  7. SpringAOP中的aop:config标签

    我们使用Spring的AOP功能的时候发现,我们使用普通的配置方式的时候,我们无法精确的确定将切面类中的哪个方法切入到哪个切入点上, 所以我们可以使用aop的专用标签来完成相关的配置.其中主要表现是使 ...

  8. [org.springframework.context.annotation.ComponentScanBeanDefinitionParser] are only available on JDK 1.5 and higher 问题--MyEclipse设置JDK版本

    org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML doc ...

  9. Context namespace element 'component-scan' and its parser class [org.springframework.context.annotation.ComponentScanBeanDefinitionParser] are only available on JDK 1.5 and higher

    异常信息如下: 错误: Unexpected exception parsing XML document from class path resource [spring/applicationCo ...

随机推荐

  1. CentOS 6.3 安装过程

    1.放入光盘 2.安装欢迎界面 进入安装欢迎界面,有四个选项: 1.“Install or upgrade an existing system”:安装或升级现有系统 2. “Install syst ...

  2. MultipeerConnectivity框架,近场通信的基本使用

    Multipeer connectivity是一个使附近设备通过Wi-Fi网络.P2P Wi-Fi以及蓝牙个人局域网进行通信的框架.互相链接的节点可以安全地传递信息.流或是其他文件资源,而不用通过网络 ...

  3. Java多线程初探

    多线程 单线程的程序只有一个顺序执行流.多个顺序流之间互不干扰. 多线程的创建 定义Thread类的子类,重写该类的run()方法. 创建Thread子类的实例. 调用线程对象的start()方法来启 ...

  4. Solr Cloud - SolrCloud

    关于 Solr Cloud Zookeeper 入门,介绍 原理 原封不动转自 http://wiki.apache.org/solr/SolrCloud/ ,文章的内存有些过时,但是了解原理. Th ...

  5. JSONObject,JSONArray,Map,String之间转换

    http://blog.csdn.net/superit401/article/details/51727739 1.String转JSONObject String jsonMessage = &q ...

  6. Evolutionary Computing: 5. Evolutionary Strategies(1)

    resource: Evolutionary computing, A.E.Eiben Outline What is Evolution Strategies Introductory Exampl ...

  7. jQuery滚动数字

    <ul class="dateList"> <li class="one"> <p class="titleName&q ...

  8. php 使用curl模拟登录discuz以及模拟发帖

    <?php$discuz_url = 'http://127.0.0.1/discuz/';//论坛地址$login_url = $discuz_url .'logging.php?action ...

  9. discuz被别人评论一段代码,然后页面就变样了

                ۣۣۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖۖ ...

  10. VHDL的参数写在一个vhd文件里

    1 参数文件top_pkg.vhd