Spring opens annotation <context:annotation-config> and <context:component-scan> interpretations and distinctions
The difference between <context:annotation-config> and <context:component-scan>
<context:annotation-config> is the annotations above that are used to activate beans that have already been registered in the Spring container, either through XML or through the package sanning.
<context:component-scan> in addition to having <context:annotation-config> functions,<context:component-scan> You can also scan and register JavaBean under the specified package.
Let's take a look at their differences in detail below, with three class a,b,c, and the B,c object is 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 Beans 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; }}
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
See below how to use <context:annotation-config> and <context:component-scan>
First, we use the Autowire method to inject the object BBB and CCC into a:
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 Beans A:" + this); } @Autowired public void setbbb (B bbb) { System.out.println ("Setting a.bbb with" + BBB); THIS.BBB = BBB; } @Autowired public void SETCCC (C CCC) { System.out.println ("Setting A.CCC with" + CCC); THIS.CCC = CCC; }}
Then Applicationcontext.xml profile Removal Properties <property> Simplify 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, obviously there is no injected attribute in ClassA, the result is wrong, what is it? 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.
This is what <context:annotation-config> does to activate beans that have already been registered in the Spring container .
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"/>
This time, 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.
But if we modify the code as follows:
Package Com.xxx;import Org.springframework.stereotype.Component, @Componentpublic class B {public B () { System.out.println ("Creating bean B:" + This);} } Package Com.xxx;import Org.springframework.stereotype.Component, @Componentpublic 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; @Componentpublic class A { private B BBB; Private C CCC; Public A () { System.out.println ("Creating Beans A:" + this); } @Autowired public void setbbb (B bbb) { System.out.println ("Setting a.bbb with" + BBB); THIS.BBB = BBB; } @Autowired public void SETCCC (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 have automatic will with @component, @service, The ability to register objects such as annotations in the spring container @Repository.
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, has been simplified to two lines context:component-scan, is not very simple?
So if we manually add the following configuration to the Applicationcontext.xml,
In other words, both the Applicationcontext.xml and the object of an instance are registered manually in the Component-scan, and the objects of B,c are scanned and registered by the following
<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,
However, the processor tool that the <context:component-scan> generates to handle those annotations will handle all the beans that are bound to the container, whether manually registered through XML or through the 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"/>
Do not worry, will not appear, the result is as follows:
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/> and <context:component-scan> exist at the same time, the former is ignored.
That is, those @autowire, @resource and so on, will only be injected once.
Even if you manually register multiple processors, spring will still only process it once:
<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"/>
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]
Category: Spring Tags: context:annotation-config, Context:component-scan
Spring opens annotation <context:annotation-config> and <context:component-scan> interpretations and distinctions