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=”**.**”/>
标签所包含,及扫描时也会注入上述实例,所以,在配置了自动扫描包配置之后,本标签可省略不配置。
springMVC之<context:annotation-config />标签的更多相关文章
- Mingyang.net:org.springframework.context.annotation.ConflictingBeanDefinitionException
org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean ...
- 【原创】大叔经验分享(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 ...
- 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 ...
- context、config
Tomcat启动时已经创建了context,并使用它读取了web.xml中的参数,后台可以从context里获取参数 后台获取参数代码: ServletContext context = getSer ...
- 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 ...
- 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. ...
- SpringAOP中的aop:config标签
我们使用Spring的AOP功能的时候发现,我们使用普通的配置方式的时候,我们无法精确的确定将切面类中的哪个方法切入到哪个切入点上, 所以我们可以使用aop的专用标签来完成相关的配置.其中主要表现是使 ...
- [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 ...
- 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 ...
随机推荐
- 如何把 Callback 接口包装成 Promise 接口
最近一段时间一直在看Node.js,在开发过程中经常要调用一些异步接口,通常在接口的最后一个参数会传入一个回调函数,可以用来处理异常,非异常情况.大致模式如下: var fs = require(“f ...
- rxjava源码中的线程知识
rxjava源码中的线程知识 rx的最精简的总结就是:异步 这里说一下以下的五个类 1.Future2.ConcurrentLinkedQueue3.volatile关键字4.AtomicRefere ...
- tcpdump用法
http://man.linuxde.net/tcpdump http://www.cnblogs.com/yc_sunniwell/archive/2010/07/05/1771563.html
- Python_Day11_同步IO和异步IO
同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network IO. ...
- DPDK编译步骤
大页内存分配: NUMA系统(现在的linux一般都是) echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048 ...
- Security » Authorization » 基于资源的授权
Resource Based Authorization¶ 基于资源的授权 68 of 73 people found this helpful Often authorization depends ...
- 今天初步了解了informix的锁的概念
今天初步了解了informix的锁的概念 2005-06-12 01:07:05 分类: IT生活 在load的时候,碰到好几次"-134 ISAM Error :no more loc ...
- Y Combinator
常见的例子 阶乘函数: fact = (a) -> if a > 0 then a * fact(a - 1) else 1 问题的提出 如上,在fact函数中调用了fact本身,无法使用 ...
- Python笔记总结week3
Set集合: 无序,不重复的序列 a. 创建 se = {"123,"456" } print(type(se)) #创建集合方式 s1 = se = {"12 ...
- ORACLE 自定义聚合函数
用户可以自定义聚合函数 ODCIAggregate,定义了四个聚集函数:初始化.迭代.合并和终止. Initialization is accomplished by the ODCIAggrega ...