Spring MVC Difference between context:annotation-config vs context:component-scan

We have already learnt the about basics of Spring MVC in my previous articles. we have used <context:annotation-config> and <context:component-scan> tags but we have not discussed much about it,In this tutorial we will see the difference between <context:annotation-config> and <context:component-scan> tags and use of them. so that we can use them effectively.

Difference between <context:annotation-config> vs <context:component-scan>

<context:annotation-config>

  • The <context:annotation-config> tag activates the annotation of the beans which is already registered in the application context. It doesn’t bother how it is registered if it is by <context:component-scan> or defined in the xml itself.
  • It mainly activates the 4 types of BeanPostProcessors
    • CommonAnnotationBeanPostProcessor : @PostConstruct, @PreDestroy, @Resource
    • AutowiredAnnotationBeanPostProcessor : @Autowired, @Value, @Inject, @Qualifier, etc
    • RequiredAnnotationBeanPostProcessor : @Required annotation
    • PersistenceAnnotationBeanPostProcessor :@PersistenceUnit and @PersistenceContext annotations

<context:component-scan>

  • The main function of <context:component-scan> tag is to register the beans to the context and also scans the annotations in the beans and activate them. In short what we can say is that <context:component-scan> does what <context:annotation-config> does as well as registers the beans to the context
    • <context:component-scan>=<context:annotation-config>+Bean Registration

Use of <context:annotation-config> and <context:component-scan>

Here we will create 3 different beans (Bean1, Bean2, Bean3) and will configure all the possible configurations to have a deeper idea about <context:component-scan> and <context:annotation-config>.

Bean1.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Bean1 
{
    private Bean2 bean2;
    private Bean3 bean3;
    
    public Bean1()
    {
        System.out.println("Creating bean bean1");
    }
    @Autowired
    public void setBean2(Bean2 bean2) {
        this.bean2 = bean2;
        System.out.println("Setting bean2 reference");
    }
    @Autowired
    public void setBean3(Bean3 bean3) {
        this.bean3 = bean3;
        System.out.println("Setting bean3 reference");
    }
}

Bean2.java

import org.springframework.stereotype.Component;

@Component
public class Bean2 
{
    public Bean2()
    {
        System.out.println("Creating bean bean2");
    }
}

Bean3.java

import org.springframework.stereotype.Component;

@Component
public class Bean3 
{
    public Bean3()
    {
        System.out.println("Creating bean bean3");
    }
}

Bean1 will have the reference of Bean2 and Bean3, and they are autowired with @Autowired annotation.

AutowireLogic.java

AutowireLogic is the base class where we read our config files and call-in the beans.

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

public class AutowireLogic 
{
    public static void main(String[] args) 
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:SpringConfig.xml");
    }
}

Now lets write our configuration file(SpringConfig.xml) in some different variations and see their differences.

1. Only Bean Tag

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

 <bean id="bean1" class="com.javainterviewpoint.Bean1"></bean>
 <bean id="bean2" class="com.javainterviewpoint.Bean2"></bean>
 <bean id="bean3" class="com.javainterviewpoint.Bean3"></bean>
</beans>

output will be

Creating bean bean1
Creating bean bean2
Creating bean bean3

Here we have created the bean and we have not set the values for the property in the Bean1

2. Bean Tag with property references

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation=" http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
 http://www.springframework.org/schema/context 
 http://www.springframework.org/schema/context/spring-context-3.0.xsd 
 http://www.springframework.org/schema/mvc 
 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

 <bean id="bean1" class="com.javainterviewpoint.Bean1">
 <property name="bean2" ref="bean2"></property>
 <property name="bean3" ref="bean3"></property>
 </bean>
 <bean id="bean2" class="com.javainterviewpoint.Bean2"></bean>
 <bean id="bean3" class="com.javainterviewpoint.Bean3"></bean>
</beans>

Output

Creating bean bean1
Creating bean bean2
Creating bean bean3
Setting bean2 reference
Setting bean3 reference

We have created the bean and we have injected reference to the property as well.

3. Only <context:annotation-config>

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation=" http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
 http://www.springframework.org/schema/context 
 http://www.springframework.org/schema/context/spring-context-3.0.xsd 
 http://www.springframework.org/schema/mvc 
 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

 <context:annotation-config></context:annotation-config>
</beans>

Output

You will get no output as we already know that <context:annotation-config> will activates the annotation of the bean which is already registered in the application context.

4. <context:annotation-config> and Bean definition

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation=" http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
 http://www.springframework.org/schema/context 
 http://www.springframework.org/schema/context/spring-context-3.0.xsd 
 http://www.springframework.org/schema/mvc 
 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

 <context:annotation-config></context:annotation-config>
 
 <bean id="bean1" class="com.javainterviewpoint.Bean1"></bean>
 <bean id="bean2" class="com.javainterviewpoint.Bean2"></bean>
 <bean id="bean3" class="com.javainterviewpoint.Bean3"></bean>
</beans>

Output

Creating bean bean1
Creating bean bean3
Setting bean3 reference
Creating bean bean2
Setting bean2 reference

Here as we have already registered the bean to the application context, <context:annotation-config> will activate the annotations over it.

5. Only <context:component-scan>

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation=" http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
 http://www.springframework.org/schema/context 
 http://www.springframework.org/schema/context/spring-context-3.0.xsd 
 http://www.springframework.org/schema/mvc 
 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

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

Output

Creating bean bean1
Creating bean bean3
Setting bean3 reference
Creating bean bean2
Setting bean2 reference

As we already know that <context:component-scan> registers the bean to the application context and as well as activates the annotation over them.

6. Putting it all together <context:component-scan>, <context:annotation-config> and Bean definition

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation=" http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.0.xsd 
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

 <context:component-scan base-package="com.javainterviewpoint"></context:component-scan>
 <context:annotation-config></context:annotation-config>
 <bean id="bean1" class="com.javainterviewpoint.Bean1" lazy-init="true"></bean>
 <bean id="bean2" class="com.javainterviewpoint.Bean2"></bean>
 <bean id="bean3" class="com.javainterviewpoint.Bean3"></bean>
</beans>

Output

Creating bean bean1
Creating bean bean3
Setting bean3 reference
Creating bean bean2
Setting bean2 reference

Even thought we have the configuration to discover the bean twice and activate the annotation, spring will fetch you the output only once.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *