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 …

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 !!

Leave a Comment

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

    In this why are both the beans B and C created first and then property assigned to bean A ? it is different than autowired .

    Reply
  2. Thank you for providing examples, which are very helping in understanding the topic rather than just theory…
    Can you please also tell what is the purpose of

    Reply
  3. excellent post. Everything is crystal clear but even though i need to execute these examples for better confidence. Thanks for the post it was really very helpful.

    Reply
  4. how to send sms from web application by using java (spring framework). Please don’t refer me JMS you can suggest me other than JMS. Send me code details.

    Reply
  5. From the context XSD namespace “Defines the configuration elements for the Spring Framework’s application context support. Effects the activation of various configuration styles for the containing Spring ApplicationContext.”

    Which means, this two annotations are spring-mvc agnostic, and they are Spring framework related

    Reply
  6. Interesting post!!!! So does it means that entry (along with package values) alone would suffice in the configuration file?

    Reply
    • Depends what you want to achieve. I am not saying what is sufficient or not. I just wanted to inform the meaning and effect of various tags when mentioned inside configuration file.

      Reply
      • I think something was missed out of my earlier comment. It is mentioned in the post that context:component-scan does what context:annotation-config does, but additionally it scan the packages and register the beans in application context. So can we omit annotation config from my configuration file if component scan is there.

        Reply

Leave a Comment

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.