Whats the difference between component-scan and annotation-config
- <context:annotation-config/> -
Looks for @Autowired and JSR annotation, It does not identify the
@component, @configuration annotations. It just autowires existing
beans
- whereas <context:component-scan base-package="org.first" /> Does recoginize @Autowired, @component and other annotations also.
- <context:component-scan> also does <context:annotation-config/> and also scans packages to find registeredbeans
Example 1 : Let's define the classes in beans.xml and also annotate with @Component and @Autowired
package org.first;
@Component public class FirstServiceImpl implements FirstService{
public Name userName;
public FirstServiceImpl(){System.out.println("new FirstServiceImpl()"); }
@Autowired
public void setUserName(final Name userName){ System.out.println("setUserName(final Name userName)"); this.userName = userName; }
//getters, setters, other constructors
}
package org.first;
@Component
public class Name{
String name = "new"; public Name(){ super();
System.out.println("new Name()");
}
//getters, setters, other constructors }
beans.xml
<beans><!-- Add Namesapece here -->
<bean name="userName" class="org.first.Name"> <property name="name" value="Vidhya"></property> </bean> <bean name="firstService" class="org.first.FirstServiceImpl"> <property name="userName" ref="userName"></property> </bean> </beans>
OUTPUT : This will instantiate the userName and firstService classes, because both classes are defined in the xml
new Name() new FirstServiceImpl() setUserName(final Name userName)
Example 2 : Lets try to use <context-annotation-config> :
package org.first;@Component public class FirstServiceImpl implements FirstService{
public Name userName;public FirstServiceImpl(){System.out.println("new FirstServiceImpl()"); }
@Autowired
public void setUserName(final Name userName){ System.out.println("setUserName(final Name userName)"); this.userName = userName; }
//getters, setters, other constructors}package org.first;public class Name{String name = "new"; public Name(){ super();System.out.println("new Name()"); }
//getters, setters, other constructors }beans.xml<beans><!-- Add Namesapece here --><context:annotation-config/>
</beans>OUTPUT : This will NOT do anything. NO OUTPUT. Why? The annotation-config cannot know about the beans unless defined.How to fix this? We need to add bean definitions. Lets add the bean definitions in the beans.xml
Example 3 : Lets use <context-annotation-config> and bring back the bean definitions.
beans.xml<beans><!-- Add Namesapece here --><context:annotation-config/>
<bean name="userName" class="org.first.Name"><property name="name" value="Vidhya"></property> </bean> <bean name="firstService" class="org.first.FirstServiceImpl"> <property name="userName" ref="userName"></property> </bean></beans>OUTPUT : This will instantiate the userName and firstService classes, because both classes are defined in the xml
new Name() new FirstServiceImpl() setUserName(final Name userName)
Example 4 : So, what's the use of annotation-config? We saw that annotation-config cannot load @component, Now lets see if it can autowire, with same class as in Example 2.
beans.xml<beans><!-- Add Namesapece here --><context:annotation-config/>
<bean name="userName" class="org.first.Name"><property name="name" value="Vidhya"></property> </bean> <bean name="firstService" class="org.first.FirstServiceImpl"><property name="userName" ref="userName"></property></bean></beans>
OUTPUT :new Name() new FirstServiceImpl() setUserName(final Name userName)Looks like annotation-config can autowire, but cannot instantiate @Component
Example 5 : Lets use <context:component-scan> now. As per definition, it can read all@component classes and also autowire. We will check that
package org.first;new FirstServiceImpl()@Component public class FirstServiceImpl implements FirstService{ public Name userName;
public FirstServiceImpl(){System.out.println("new FirstServiceImpl()"); }
@Autowired
public void setUserName(final Name userName){ System.out.println("setUserName(final Name userName)"); this.userName = userName; }
//getters, setters, other constructors}package org.first;@Component public class Name{
String name = "new"; public Name(){ super();System.out.println("new Name()"); }
//getters, setters, other constructors }beans.xml<beans><!-- Add Namespace here --><context:component-scan base-package="org.first" />
</beans>OUTPUT : There you go.. Now we achieve with single line in beans.xml, which all @Component and @Autowired annotations.
new Name()
setUserName(final Name userName)
SUMMARY:
1. <context:component-scan> is one stop solution for @Autowired and @Component
2.<context:annotation-config> can only do @Autowired.3. I am readying the annotation-config is very useful in the web context with DispatcherServlet. But need to try that. Probably will write about it later when I try it.
References
http://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s11.html
http://www.tutorialspoint.com/spring/spring_annotation_based_configuration.htmhttp://stackoverflow.com/questions/7414794/difference-between-contextannotation-config-vs-contextcomponent-scan