Spring context:annotation-config vs context:component-scan

Learn the main differences between tags <context:annotation-config> and <context:component-scan> in Spring MVC applications so that when we use them in the future, we will know, what exactly we are doing.

1. The Differences between <context:annotation-config> vs <context:component-scan>

The first big difference between both tags is that <context:annotation-config> is used to activate applied annotations in already registered beans in the 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.

The second difference is driven by the first difference itself. The component-scan does register the beans in context, as well as, it also scans the annotations inside the beans and activates them. So <context:component-scan>; does what <context:annotation-config> does, but additionally, it scan the packages and registers the beans in the application context.

2. Demo

I will elaborate on both tags in detail with some examples which will make more sense to us. For keeping the example simple, I am creating just 3 beans, and I will try to configure them in the configuration file in various ways, then we will see the difference between various configurations in the console where the output will get printed.

2.1. Setup

For reference, below are 3 beans. BeanA has reference to BeanB and BeanC additionally.

@Component
public class BeanA {

	private BeanB beanB;
	private BeanC beanC;

	public BeanA(){
		System.out.println("Creating bean BeanA");
	}

	@Autowired
	public void setBeanB(BeanB beanB) {
		System.out.println("Setting bean reference for BeanB");
		this.beanB = beanB;
	}

	@Autowired
	public void setBeanC(BeanC beanC) {
		System.out.println("Setting bean reference for BeanC");
		this.beanC = beanC;
	}
}
@Component
public class BeanB {
	public BeanB(){
		System.out.println("Creating bean BeanB");
	}
}
@Component
public class BeanC {
	public BeanC(){
		System.out.println("Creating bean BeanC");
	}
}

The following BeanDemo class is used to load and initialize the application context.

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanDemo {
	public static void main(String[] args) {

		ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
	}
}

Now let’s start writing the configuration file "beans.xml" with variations. I will be omitting the schema declarations in the below examples, to keep focus on the configuration itself.

2.2. Define Only the Bean Tags

<bean id="beanA" class="com.howtodoinjava.beans.BeanA"></bean>
<bean id="beanB" class="com.howtodoinjava.beans.BeanB"></bean>
<bean id="beanC" class="com.howtodoinjava.beans.BeanC"></bean>

In this case, all 3 beans are created and no dependency is injected in BeanA because we didn’t use any property/ref attributes.

Creating bean BeanA
Creating bean BeanB
Creating bean BeanC

2.3. Define bean tags and property ref attributes

<bean id="beanA" class="com.howtodoinjava.beans.BeanA">
  <property name="beanB" ref="beanB"></property>
  <property name="beanC" ref="beanC"></property>
</bean>

<bean id="beanB" class="com.howtodoinjava.beans.BeanB"></bean>
<bean id="beanC" class="com.howtodoinjava.beans.BeanC"></bean>

Now the beans are created and injected as well. No wonder.

Creating bean BeanA
Creating bean BeanB
Creating bean BeanC

Setting bean reference for BeanB
Setting bean reference for BeanC

2.4. Using only <context:annotation-config />

<context:annotation-config />

As I told you already, <context:annotation-config /> activates the annotations only on beans that have already been discovered and registered. Here, we have not discovered any beans so nothing happened.

//Prints Nothing

2.5. Using <context:annotation-config /> with bean declarations

<context:annotation-config />
<bean id="beanA" class="com.howtodoinjava.beans.BeanA"></bean>
<bean id="beanB" class="com.howtodoinjava.beans.BeanB"></bean>
<bean id="beanC" class="com.howtodoinjava.beans.BeanC"></bean>

In the 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.

Creating bean BeanA
Creating bean BeanB
Setting bean reference for BeanB
Creating bean BeanC
Setting bean reference for BeanC

2.6. Using only <context:component-scan />

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

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).

Creating bean BeanA
Creating bean BeanB
Setting bean reference for BeanB
Creating bean BeanC
Setting bean reference for BeanC

2.7. Using both <context:component-scan /> and <context:annotation-config />

<context:annotation-config />
<context:component-scan base-package="com.howtodoinjava.beans" />
<bean id="beanA" class="com.howtodoinjava.beans.BeanA"></bean>
<bean id="beanB" class="com.howtodoinjava.beans.BeanB"></bean>
<bean id="beanC" class="com.howtodoinjava.beans.BeanC"></bean>
Creating bean BeanA
Creating bean BeanB
Setting bean reference for BeanB
Creating bean BeanC
Setting bean reference for BeanC

Strange !! With the above configuration, we are discovering beans two times and activating annotations two times as well. But the output got printed one time only. Why? Because spring is intelligent enough to register any configuration processing only once if it is registered multiple tiles using the same or different ways. Cool !!

So, Here I am ending this tutorial and hoping that it will give a more clear picture to you guys when you use these tags in your next project. Feel free to download the sourcecode and play with it.

Happy Learning !!

Comments

Subscribe
Notify of
guest
23 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.