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 ...
随机推荐
- LMAX Disruptor—多生产者多消费者中,消息复制分发的高性能实现
解决的问题 当我们有多个消息的生产者线程,一个消费者线程时,他们之间如何进行高并发.线程安全的协调? 很简单,用一个队列. 当我们有多个消息的生产者线程,多个消费者线程,并且每一条消息需要被所有的消费 ...
- 你的指纹还安全吗? - BlackHat 2015 黑帽大会总结 day 2
你的指纹还安全吗? 0x03 FINGERPRINTS ON MOBILE DEVICES: ABUSING AND LEAKING speaker是来自FireEye的Wei Tao和Zhang ...
- jQuery.is() 函数
is() 函数 判断当前对象是否符合指定表达式 语法 $selector.is(表达式)//指定表达式 返回值 返回值为布尔型(true/false) 当当前对象包含多个元素时,只要任意元素满足指定表 ...
- YYCache设计思路及源码学习
设计思路 利用YYCache来进行操作,实质操作分为了内存缓存操作(YYMemoryCache)和硬盘缓存操作(YYDiskCache).内存缓存设计一般是在内存中开辟一个空间用以保存请求的数据(一般 ...
- 原创:Equinox OSGi应用嵌入Jersey框架搭建REST服务
一.环境 eclipse版本:eclipse-luna 4.4 jre版本:1.8 二.Equinox OSGi应用嵌入Jersey框架搭建REST服务 1.新建插件工程HelloWebOSGI a. ...
- Goppa code
上面的公式定义了长度为n的Goppa码[1].n=2^m, 其维度 k≥n- t·m. 最小距离d≥ 2t+1. 存在运行时间与 n·t 成正比的快速译码算法. 从形式上看,右边是分式,相当于线性分组 ...
- thinkphp发邮件失败原因
使用phpmailer出现连接失败, 代码是别人已经封装好的没有问题,可能原因有如下. qq提示: SMTP server error: mail from address must be same ...
- Android之常用Git命令
Android之常用Git命令 代码修改后提交步骤:git status:查看代码修改状态git diff:查看代码修改细节,也能看代码空格git add . :添加新加入的代码git commit ...
- plist基本操作
重要概念:某些路径下“只能读,不能写”的原因 iPhone.ipad真机上 Resouces文件夹:是只读的,无法写入. document 和temp文件夹:可读,可写. 一.工程结构
- IntelliJ IDEA中Maven项目的默认JDK版本
在IntelliJ IDEA 15中使用Maven时,IDEA将默认的编译版本.源码版本设置为jdk5.编译项目的时候出现警告:"Warning:Java: 源值1.5已过时, 将在未来所有 ...