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 auto-wired 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.
kumar says
Excellent explanation. Thank you!