The difference between <context:annotation-config> and <context:component-scan>

Source: Internet
Author: User

Turn from: Good spring <context:annotation-config> <context:component-scan> interpretation and differences

<context:annotation-config>The annotations above that are used to activate a bean that has already been registered in the spring container (either through XML or through the package sanning) is an annotation processing tool that simply injects, regardless of the registered bean.

<context:component-scan> 除了具有<context:annotation-config>的功能之外,<context:component-scan>You can also scan and register JavaBean under the specified package, that is, both inject and register beans.

Let's look at their differences in detail in the examples below,

There are three class a,b,c, and the B,c object is injected into A.

 Packagecom.xxx;  Public classB { PublicB () {System.out.println ("Creating bean B:" + This); }  }     Packagecom.xxx;  Public classC { PublicC () {System.out.println ("Creating bean C:" + This); }  }     Packagecom.yyy; Importcom.xxx.b; Importcom.xxx.c;  Public classA {PrivateB BBB; PrivateC CCC;  PublicA () {System.out.println ("Creating bean A:" + This); }     Public voidsetbbb (B bbb) {System.out.println ("Setting a.bbb with" +BBB);  This. BBB =BBB; }     Public voidSETCCC (C CCC) {System.out.println ("Setting A.CCC with" +CCC);  This. CCC =CCC; }  }   

Add the following configuration to the Applicationcontext.xml:

<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 Applicationcontext.xml configuration file, you will get the following result:

Creating bean B: [Email protected]creating bean C: [Email protected]creating bean A: [email protected]setting a.bbb with [ Email protected]setting A.CCC with [email protected]

OK, this result is nothing to say, is completely through the XML way, but too outdated, the following annotated way to simplify our XML configuration file

First, we use the Autowire method to inject the object BBB and CCC into a:

 Packagecom.yyy; Importorg.springframework.beans.factory.annotation.Autowired; Importcom.xxx.b; Importcom.xxx.c;  Public classA {PrivateB BBB; PrivateC CCC;  PublicA () {System.out.println ("Creating bean A:" + This); } @Autowired Public voidsetbbb (B bbb) {System.out.println ("Setting a.bbb with" +BBB);  This. BBB =BBB; } @Autowired Public voidSETCCC (C CCC) {System.out.println ("Setting A.CCC with" +CCC);  This. CCC =CCC; }  }   

We can then remove the following configuration from the Applicationcontext.xml

<property name= "BBB" ref= "Bbean"/><property name= "CCC" ref= "Cbean"/>

After removal, our applicationcontext.xml configuration file is simplified to look like this

<bean id= "Bbean"class= "com.xxx.b"/><bean id= "Cbean"class= "com.xxx.c"/><bean id= " Abean "class=" Com.yyy.a "/>

When we load the Applicationcontext.xml configuration file, we get the following result:

Creating bean B: [Email protected]creating bean C: [Email protected]creating bean A: [Email protected]

OK, the result is wrong, what is the reason? Why is our attribute not injected into it?

Because the annotations themselves are not capable of doing anything, they are just the most basic components, and we need a processing tool that can handle these annotations

这就是<context:annotation-config>The things that are done

We will modify the Applicationcontext.xml configuration file as follows:

<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 we load the Applicationcontext.xml configuration file, we get the following result:

Creating bean B: [Email protected]creating bean C: [Email protected]creating bean A: [email protected]setting a.bbb with [ Email protected]setting A.CCC with [email protected]

OK, the results are correct.

The following shows the difference between <context:annotation-config> and <context:component-scan>:

But if we modify the code as follows:

 Packagecom.xxx; Importorg.springframework.stereotype.Component; @Component Public classB { PublicB () {System.out.println ("Creating bean B:" + This); }  }     Packagecom.xxx; Importorg.springframework.stereotype.Component; @Component Public classC { PublicC () {System.out.println ("Creating bean C:" + This); }  }     Packagecom.yyy; Importorg.springframework.beans.factory.annotation.Autowired; Importorg.springframework.stereotype.Component; Importcom.xxx.b; Importcom.xxx.c; @Component Public classA {PrivateB BBB; PrivateC CCC;  PublicA () {System.out.println ("Creating bean A:" + This); } @Autowired Public voidsetbbb (B bbb) {System.out.println ("Setting a.bbb with" +BBB);  This. BBB =BBB; } @Autowired Public voidSETCCC (C CCC) {System.out.println ("Setting A.CCC with" +CCC);  This. CCC =CCC; }  }  

The Applicationcontext.xml configuration file is modified to:

<context:annotation-config/>

When we load the Applicationcontext.xml configuration file, but there is no output, why?

That's because <context:annotation-config/> can only work on beans that have already been registered.

For beans that are not registered in the spring container, it is not capable of performing any operations.

But do not worry, <context:component-scan>除了具有 <context:annotation-config/> function, but also has automatic will with @component, @service, @ Repository objects such as annotations are registered with the spring container.

We will modify the Applicationcontext.xml configuration file as follows:

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

When we load the applicationcontext.xml, we get the following result:

Creating bean B: [Email protected]creating bean C: [Email protected]

What is the reason for this?

Because we only scanned the classes of the COM.XXX package and its sub-packages, and Class A was under the COM.YYY package, so we couldn't scan the

Let's add com.yyy to the Applicationcontext.xml:

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

Then load the applicationcontext.xml and you will get the following result:
Creating bean B: [Email protected]creating bean C: [Email protected]creating bean A: [email protected]setting a.bbb with [ Email protected]setting A.CCC with [email protected]

Wow, the results are correct!

Looking back at our Applicationcontext.xml file, it has been simplified to:

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

The

So if we manually add the following configuration to the Applicationcontext.xml, that is to say, the instance object of a is registered manually in Applicationcontext.xml, and by Component-scan to scan and register B, Object of C

<context:component-scan base-package = "Com.xxx"/><bean id= "Abean"class= "Com.yyy.a"/ >

The result is still correct:

Creating bean B: [Email protected]creating bean C: [Email protected]creating bean A: [email protected]setting a.bbb with [ Email protected]setting A.CCC with [email protected]

Although Class A is not registered in a container by scanning, the <context:component-scan> resulting processor tool that handles those annotations handles all the beans that are bound to the container, whether manually registered through XML or through a scanning scan.

So, what if we go through the following way? We have configured the <context:annotation-config/>, and also configured the <context:component-scan base-package= "com.xxx"/> They all have the ability to handle annotations within the bean registered in the container. Will there be repeated injections of the situation?

<context:annotation-config/><context:component-scan base-package = "Com.xxx"/><bean id= " Abean "class=" Com.yyy.a "/>

Don't worry, it won't happen:

Creating bean B: [Email protected]creating bean C: [Email protected]creating bean A: [email protected]setting a.bbb with [ Email protected]setting A.CCC with [email protected]

Because <context:annotation-config />和<context:component-scan>同时存在的时候,前者会被忽略。也就是那些@autowire,@resource等注入注解只会被注入一次

Even if you manually register multiple processors, spring will still only process it once:

<context:annotation-config/>  <context:component-scan base-package = "Com.xxx"/>   Class= "Com.yyy.a"/>  class= " Org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor "/>  class=" Org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor "/>  class=" Org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor "/>  class= "Org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>  

The result is still correct:

Creating bean B: [Email protected]creating bean C: [Email protected]creating bean A: [email protected]setting a.bbb with [ Email protected]setting A.CCC with [email protected]

The difference between <context:annotation-config> and <context:component-scan>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.