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