本文摘自stack overflow.详细解释请看如下:

http://stackoverflow.com/questions/7414794/difference-between-contextannotation-config-vs-contextcomponent-scan


<context:annotation-config>
 is used to activate annotations in beans already registered in the application context (no matter if they were defined with XML or by package scanning).

<context:component-scan> can also do what <context:annotation-config> does

but <context:component-scan> also scans packages to find and register beans within the application context.

I'll use some examples to show the differences/similarities.

Lets start with a basic setup of three beans of type AB and C, with B and C being injected into A.

package com.xxx;
public class B {public B() {System.out.println("creating bean B: " + this);}
}package com.xxx;
public class C {public C() {System.out.println("creating bean C: " + this);}
}package com.yyy;
import com.xxx.B;
import com.xxx.C;
public class A { private B bbb;private C ccc;public A() {System.out.println("creating bean A: " + this);}public void setBbb(B bbb) {System.out.println("setting A.bbb with " + bbb);this.bbb = bbb;}public void setCcc(C ccc) {System.out.println("setting A.ccc with " + ccc);this.ccc = ccc; }
}

With the following XML configuration :

<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A"><property name="bbb" ref="bBean" /><property name="ccc" ref="cBean" />
</bean>

Loading the context produces the following output:

creating bean B: com.xxx.B@c2ff5
creating bean C: com.xxx.C@1e8a1f6
creating bean A: com.yyy.A@1e152c5
setting A.bbb with com.xxx.B@c2ff5
setting A.ccc with com.xxx.C@1e8a1f6

OK, this is the expected output. But this is "old style" Spring. Now we have annotations so lets use those to simplify the XML.

First, lets autowire the bbb and ccc properties on bean A like so:

package com.yyy;
import org.springframework.beans.factory.annotation.Autowired;
import com.xxx.B;
import com.xxx.C;
public class A { private B bbb;private C ccc;public A() {System.out.println("creating bean A: " + this);}@Autowiredpublic void setBbb(B bbb) {System.out.println("setting A.bbb with " + bbb);this.bbb = bbb;}@Autowiredpublic void setCcc(C ccc) {System.out.println("setting A.ccc with " + ccc);this.ccc = ccc;}
}

This allows me to remove the following rows from the XML:

This allows me to remove the following rows from the XML:

<property name="bbb" ref="bBean" />
<property name="ccc" ref="cBean" />

My XML is now simplified to this:

<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A" />

When I load the context I get the following output:

creating bean B: com.xxx.B@5e5a50
creating bean C: com.xxx.C@54a328
creating bean A: com.yyy.A@a3d4cf

OK, this is wrong! What happened? Why aren't my properties autowired?

Well, annotations are a nice feature but by themselves they do nothing whatsoever. They just annotate stuff. You need a processing tool to find the annotations and do something with them.

<context:annotation-config> to the rescue. This activates the actions for the annotations that it finds on the beans defined in the same application context where itself is defined.

If I change my XML to this:

<context:annotation-config />
<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A" />

when I load the application context I get the proper result:

creating bean B: com.xxx.B@15663a2
creating bean C: com.xxx.C@cd5f8b
creating bean A: com.yyy.A@157aa53
setting A.bbb with com.xxx.B@15663a2
setting A.ccc with com.xxx.C@cd5f8b

OK, this is nice, but I've removed two rows from the XML and added one. That's not a very big difference. The idea with annotations is that it's supposed to remove the XML.

So let's remove the XML definitions and replace them all with annotations:

public class B {public B() {System.out.println("creating bean B: " + this);}
}package com.xxx;
import org.springframework.stereotype.Component;
@Component
public class C {public C() {System.out.println("creating bean C: " + this);}
}package com.yyy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.xxx.B;
import com.xxx.C;
@Component
public class A { private B bbb;private C ccc;public A() {System.out.println("creating bean A: " + this);}@Autowiredpublic void setBbb(B bbb) {System.out.println("setting A.bbb with " + bbb);this.bbb = bbb;}@Autowiredpublic void setCcc(C ccc) {System.out.println("setting A.ccc with " + ccc);this.ccc = ccc;}
}

While in the XML we only keep this:

<context:annotation-config />

We load the context and the result is... Nothing. No beans are created, no beans are autowired. Nothing!

That's because, as I said in the first paragraph, the <context:annotation-config /> only works on beans registered within the application context. Because I removed the XML configuration for the three beans there is no bean created and <context:annotation-config /> has no "targets" to work on.

But that won't be a problem for <context:component-scan> which can scan a package for "targets" to work on. Let's change the content of the XML config into the following entry:

<context:component-scan base-package="com.xxx" />

When I load the context I get the following output:

creating bean B: com.xxx.B@1be0f0a
creating bean C: com.xxx.C@80d1ff

Hmmmm... something is missing. Why?

If you look closelly at the classes, class A has package com.yyy but I've specified in the <context:component-scan> to use package com.xxx so this completely missed my A class and only picked up B and C which are on the com.xxx package.

To fix this, I add this other package also:

<context:component-scan base-package="com.xxx,com.yyy" />

and now we get the expected result:

creating bean B: com.xxx.B@cd5f8b
creating bean C: com.xxx.C@15ac3c9
creating bean A: com.yyy.A@ec4a87
setting A.bbb with com.xxx.B@cd5f8b
setting A.ccc with com.xxx.C@15ac3c9

And that's it! Now you don't have XML definitions anymore, you have annotations.

As a final example, keeping the annotated classes AB and C and adding the following to the XML, what will we get after loading the context?

<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />

We still get the correct result:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

Even if the bean for class A isn't obtained by scanning, the processing tools are still applied by <context:component-scan> on all beans registered in the application context, even for A which was manually registered in the XML.

But what if we have the following XML, will we get duplicated beans because we've specified both <context:annotation-config /> and <context:component-scan>?

<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />

No, no duplications, We again get the expected result:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

That's because both tags register the same processing tools (<context:annotation-config /> can be omitted if <context:component-scan> is specified) but Spring takes care of running them only once.

Even if you register the processing tools yourself multiple times, Spring will still make sure they do their magic only once; this XML:

<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />
<bean id="bla" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla1" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla2" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla3" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />

will still generate the following result:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@25d2b2
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

OK, that about raps it up.

I hope this information along with the responses from @Tomasz Nurkiewicz and @Sean Patrick Floyd are all you need to understand how <context:annotation-config> and <context:component-scan>work.

context:annotation-config vs context:component-scan 的区别相关推荐

  1. springbbot运行无法编译成功,找不到jar包报错:Error:(3, 46) java: 程序包org.springframework.context.annotation不存在

    文章目录 问题描述: 解决方案: 问题描述: 提示:idea springbbot运行无法编译成功,找不到jar包报错 E:\ideaProject\demokkkk\src\main\java\co ...

  2. Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException 异常

    Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException 异常 参考文章: (1)Cau ...

  3. 已解决org.springframework.context.annotation.ConflictingBeanDefinitionException异常的正确解决方法,亲测有效!!!

    已解决org.springframework.context.annotation.ConflictingBeanDefinitionException异常的正确解决方法,亲测有效!!! 文章目录 报 ...

  4. org.springframework.context.annotation.ConflictingBeanDefinitionException异常处理

    问题描述: 项目启动时,报了这个错: org.springframework.context.annotation.ConflictingBeanDefinitionException:标记为Bean ...

  5. org.springframework.context.annotation.AnnotationConfigApplicationContext has not been refreshed yet

    代码如下(为了演示这个报错): AnnotationConfigApplicationContext annotationConfigApplicationContext = new Annotati ...

  6. 【问题解决】Error:(3, 46) java: 程序包org.springframework.context.annotation不存在

    Error:(3, 46) java: 程序包org.springframework.context.annotation不存在 我本地的解决办法是 File->Settings->Bui ...

  7. org.springframework.context.annotation.AnnotationConfigApplicationContext has been closed already

    ** org.springframework.context.annotation.AnnotationConfigApplicationContext has been closed already ...

  8. 从 Context 家谱来聊一聊 Context 家族使用的设计模式?

    Context Context 被翻译成上下文,是应用程序环境的全局信息接口,它是一个抽象类,其实现由 Android 系统提供的 ContextImpl 类.我们通过 Context 可以非常方便的 ...

  9. @Component与@Configuration区别

    @Component与@Configuration区别: @Configuration本质上还是@Component. @Configuration标记的类必须符合下面的要求: 1.配置类不能是 fi ...

  10. INDEX FULL SCAN和INDEX FAST FULL SCAN的区别

    2019独角兽企业重金招聘Python工程师标准>>> 关于INDEX FULL SCAN和INDEX FAST FULL SCAN的区别在于,前者在对索引进行扫描的时候会考虑大索引 ...

最新文章

  1. SimpleDelegate 委托
  2. 2017202110104-高级软件工程2017第8次作业—个人总结
  3. Java PECS
  4. Rosenbrock函数到底什么用
  5. 分区供水条件口诀_口诀记忆 | 消防给水和消火栓系统的“月检”(重点学习)...
  6. 面向对象开发的五大基本原则
  7. codechef Polo the Penguin and the Tree
  8. ARM指令 LDR 和 ADR的一些区别
  9. Windows7 Xp Mode部署与讲解
  10. mysql某个表的列除以2_数据库mysql(二)
  11. 【java】Java 中的 Exchanger 线程同步使用方法 线程之间交换数据
  12. 封装成jar包_通用源码阅读指导mybatis源码详解:io包
  13. Scrapy运行时出现的错误 :exception.ImportError No module named win32api
  14. OpenCore启动项中无Install macOS Big Sur 的解决办法
  15. CTD数据库(Comparative Toxicogenomics Database)介绍与使用
  16. 科密t1消费管理系统_科密A1\T1登录密码获取软件-科密A1\T1登录密码获取工具1.0.0 安卓版-东坡下载...
  17. 2019 版idea设置字体大小
  18. fgo升级经验计算机,命运冠位指定狗粮本每日经验表 fgo国服狗粮本刷取技巧攻略[多图]...
  19. 解决注册表被禁用的问题
  20. sklearn.datasets.base中Bunch类

热门文章

  1. 使用while循环方式打印100以内4的倍数(while中加if)、使用while循环方式计算2+4+6+8+...+100、编写程序“从键盘读入个数不正确的整数,并判断读入的正数和负数的个数
  2. vi与vim编辑器使用
  3. CTF训练 SSH服务(1)
  4. 踩坑,union后数据少了
  5. 大白话学习JVM(01)| 10分钟带你走进JVM的生活
  6. 预约下单同城服务小程序开发
  7. 调用百度地图出现的自动创建完成对象会清空输入框值的问题
  8. 权益对账稽核该怎么做
  9. Python第4次作业——魏祥民
  10. SWAN测试执行流程