1) First big difference between both tags is that <context:annotation-config>
is used to activate applied annotations in already registered beans in application context. Note that it simply does not matter whether bean was registered by which mechanism e.g. using<context:component-scan>
or it was defined in application-context.xml file itself.2) Second difference is driven from first difference itself. It registers the beans defined in config file into context + it also scans the annotations inside beans and activate them. So<context:component-scan>
does what <context:annotation-config>
does, but additionally it scan the packages and register the beans in application context.
<context:annotation-config> = Scanning and activating annotations in “already registered beans”.
<context:component-scan> = Bean Registration + Scanning and activating annotations
We have already learned few things in Spring MVC in previous posts. In those tutorials, I did use tags like <context:annotation-config>
or <context:component-scan>
, but I didn’t explained much in detail about these tags. I am writing this post, specifically to list down the difference between tags <context:annotation-config>
and <context:component-scan>
so that when you use them in future, you will know, what exactly are you doing.1) First big difference between both tags is that <context:annotation-config>
is used to activate applied annotations in already registered beans in application context. Note that it simply does not matter whether bean was registered by which mechanism e.g. using<context:component-scan>
or it was defined in application-context.xml file itself.2) Second difference is driven from first difference itself. It does register the beans in context + it also scans the annotations inside beans and activate them. So <context:component-scan>
; does what <context:annotation-config>
does, but additionally it scan the packages and register the beans in application context.
Example of <context:annotation-config> vs <context:component-scan> uses
I will elaborate both tags in detail with some examples which will make more sense to us. For keeping the example to simple, I am creating just 3 beans, and I will try to configure them in configuration file in various ways, then we will see the difference between various configurations in console where output will get printed.For reference, below are 3 beans. BeanA
has reference to BeanB
and BeanC
additionally.
packagecom.howtodoinjava.beans;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.stereotype.Component;
@SuppressWarnings("unused")
@Component
publicclassBeanA {
privateBeanB beanB;
privateBeanC beanC;
publicBeanA(){
System.out.println("Creating bean Bean A");
}
@Autowired
Public void setBeanB(BeanB beanB) {
System.out.println("Setting bean reference for BeanB");
this.beanB = beanB;
}
@Autowired
publicvoidsetBeanC(BeanC beanC) {
System.out.println("Setting bean reference for BeanC");
this.beanC = beanC;
}
}
//Bean B
packagecom.howtodoinjava.beans;
importorg.springframework.stereotype.Component;
@Component
publicclassBeanB {
publicBeanB(){
System.out.println("Creating bean BeanB");
}
}
//Bean C
packagecom.howtodoinjava.beans;
importorg.springframework.stereotype.Component;
@Component
publicclassBeanC {
publicBeanC(){
System.out.println("Creating bean BeanC");
}
}
|
BeanDemo
class is used to load and initialize the application context.
packagecom.howtodoinjava.test;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
publicclassBeanDemo {
publicstaticvoidmain(String[] args) {
ApplicationContext context = newClassPathXmlApplicationContext("classpath:beans.xml");
}
}
|
Now let’s start writing the configuration file "beans.xml"
with variations. I will be omitting the schema declarations in below examples, to keep focus on configuration itself.
a) Define only bean tags
<beanid="beanA"class="com.howtodoinjava.beans.BeanA"></bean>
<beanid="beanB"class="com.howtodoinjava.beans.BeanB"></bean>
<beanid="beanC"class="com.howtodoinjava.beans.BeanC"></bean>
Output:
Creating bean BeanA
Creating bean BeanB
Creating bean BeanC
|
In this case, all 3 beans are created and no dependency in injected in BeanA
because we didn’t used any property/ref attributes.
b) Define bean tags and property ref attributes
<beanid="beanA"class="com.howtodoinjava.beans.BeanA">
<propertyname="beanB"ref="beanB"></property>
<propertyname="beanC"ref="beanC"></property>
</bean>
<beanid="beanB"class="com.howtodoinjava.beans.BeanB"></bean>
<beanid="beanC"class="com.howtodoinjava.beans.BeanC"></bean>
Output:
Creating bean BeanA
Creating bean BeanB
Creating bean BeanC
Setting bean reference for BeanB
Setting bean reference for BeanC
|
Now the beans are created and injected as well. No wonder.
c) Using only <context:annotation-config />
<context:annotation-config/>
//No Output
|
As I told already, <context:annotation-config />
activate the annotations only on beans which have already been discovered and registered. Here, we have not discovered any bean so nothing happened.
d) Using <context:annotation-config /> with bean declarations
<context:annotation-config/>
<beanid="beanA"class="com.howtodoinjava.beans.BeanA"></bean>
<beanid="beanB"class="com.howtodoinjava.beans.BeanB"></bean>
<beanid="beanC"class="com.howtodoinjava.beans.BeanC"></bean>
Output:
Creating bean BeanA
Creating bean BeanB
Setting bean reference for BeanB
Creating bean BeanC
Setting bean reference for BeanC
|
In above configuration, we have discovered the beans using <bean> tags. Now when we use<context:annotation-config />
, it simply activates @Autowired
annotation and bean injection inside BeanA
happens.
e) Using only <context:component-scan />
<context:component-scanbase-package="com.howtodoinjava.beans"/>
Output:
Creating bean BeanA
Creating bean BeanB
Setting bean reference for BeanB
Creating bean BeanC
Setting bean reference for BeanC
|
Above configuration does both things as I mentioned earlier in start of post. It does the bean discovery (searches for @Component
annotation in base package) and then activates the additional annotations (e.g. Autowired
).
f) Using both <context:component-scan /> and <context:annotation-config />
<context:annotation-config/>
<context:component-scanbase-package="com.howtodoinjava.beans"/>
<beanid="beanA"class="com.howtodoinjava.beans.BeanA"></bean>
<beanid="beanB"class="com.howtodoinjava.beans.BeanB"></bean>
<beanid="beanC"class="com.howtodoinjava.beans.BeanC"></bean>
Output:
Creating bean BeanA
Creating bean BeanB
Setting bean reference for BeanB
Creating bean BeanC
Setting bean reference for BeanC
|
No comments:
Post a Comment