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. 使用Maven JGit-Flow Plugin

    git flow 请参考 http://www.ituring.com.cn/article/56870 2.开始使用插件,在pom.xml中添加以下代码: https://bitbucket.org ...

  2. Node聊天程序实例04:chat_ui.js

    作者:vousiu 出处:http://www.cnblogs.com/vousiu 本实例参考自Mike Cantelon等人的<Node.js in Action>一书. 这个程序在客 ...

  3. java 重载规则

    首先看Java重载的规则: 1.必须具有不同的参数列表: 2.可以有不同的返回类型,只要参数列表不同就可以: 3.可以有不同的访问修饰符: 4.可以抛出不同的异常: 5.方法能够在一个类中或者在一个子 ...

  4. web 打开子窗口提交数据或其他操作后 关闭子窗口且刷新父窗口实现

    父页面 : html连接:<a href="javascript:void(0)" onclick="window.open(子页面URL)">js ...

  5. VB调用sendinput API

    http://files.cnblogs.com/files/liuzhaoyzz/VB%E8%B0%83%E7%94%A8sendinput_API.rar sendinput只支持发送字符或者组合 ...

  6. 设置DataSource后DateGridView不显示的问题

    在一个WinForm小程序中,有两处需要用DataGridView控件显示数据.设置DataGridView.DataSource为数据查询结果后,第一个DataGridView可以正常显示数据,而第 ...

  7. linux centos 安装mysql

    安装步骤 http://www.cnblogs.com/gaojupeng/p/5727069.html 下面这个报错 主要还是在 题啊加软连接的   命令出了问题 1.启动  报错 mysqld_s ...

  8. android Glide图片加载框架的初探

    一.Glide图片加载框架的简介 谷歌2014年开发者论坛会上介绍的图片加载框架,它让我们在处理不管是网路下载的图片还是本地的图片,减轻了很多工作量, 二.开发步骤: 1.添加链接库 compile ...

  9. 里面的div怎么撑开外面的div,让高度自适应

    关于容器高度自适应的兼容性问题.1.有些时候,我们希望容器有一个固定高度,但当其中的内容多的时候,又希望高度能够自适应,也即容器在纵向能被撑开,且如果有背景,也能够自适应.在一般情况下,使用min-h ...

  10. 【转】OPENGL基本API概述

    本文信息资源来源于网络,欢迎转载!转载时请保留本文链接(http://www.shopliyang.com.cn/)! OpenGL中的gl库是核心库,glu是实用库,glut是实用工具库. gl是核 ...