I came across two annotations provided by Spring 3 (@Component and @Configuration)
I am a bit confused between these.
Here is what I read about @Component
Put this “context:component” in bean configuration file, it means,
enable auto scanning feature in Spring. The base-package is indicate
where are your components stored, Spring will scan this folder and
find out the bean (annotated with @Component) and register it in
Spring container.
So I am wondering what is the use of @Configuration then if @Controller will register my beans without the need to declare them in spring configuration xml file
@Configuration
is the heart of the Java-based configuration mechanism that was introduced in Spring 3. It provides an alternative to XML-based configuration.
So the 2 following snippets are identical:
<beans ...>
<context:component-scan base-package="my.base.package"/>
... other configuration ...
</beans>
and:
@Configuration
@ComponentScan(basePackages = "my.base.package")
public class RootConfig {
... other configuration ...
}
In both cases Spring will scan in my.base.package
and below for classes annotated with @Component
or one of the other annotations that are meta-annotated with @Component
such as @Service
.
From Book Pro Spring Integration
@Configuration
classes are just like regular @Components
classes, except that methods annotated with @Bean
are used to factory beans. Note that a @Component
with @Bean
annotated methods works the same way, except that scopes are not respected and the @Bean
methods are re-invoked (no caching in play), so @Configuration
is preferred, even though it requires CGLIB
Here is difference with full example :-
//@Configuration or @Component
public static class Config {
@Bean
public A a() {
return new A();
}
//**please see a() method called inside b() method**
@Bean
public B b() {
return new B(a());
}
}
1) Here if Config class annotated with @configuration , than a() method and b() method , both will be called once .
2)Here if Config class annotated with @component , than b() method will be called once but a() method will be called twice .
Problem in (2) :- since we have noticed the problem with @component annotation .
This second configuration (2) is totally incorrect because spring will create a singleton bean of A, but B will obtain another instance of A which is out of the spring context control.
Solution :- we can use @autowired annotation with @component annotation inside Config class .
@Component
public static class Config {
@Autowired
A a;
@Bean
public A a() {
return new A();
}
@Bean
public B b() {
return new B(a);
}
}
Although this is old, but elaborating on JavaBoy And Vijay's answers, with an example:
@Configuration
public class JavaConfig {
@Bean
public A getA() {
return new A();
}
}
@Component
@ComponentScan(basePackages="spring.example")
public class Main() {
@Bean
public B getB() {
return new B();
}
@Autowired
JavaConfig config;
public static void main(String[]a) {
Main m = new AnnotationConfigApplicationContext(Main.class)
.getBean(Main.class);
/* Different bean returned everytime on calling Main.getB() */
System.out.println(m.getB());
System.out.println(m.getB());
/* Same bean returned everytime on calling JavaConfig.getA() */
System.out.println(m.config.getA());
System.out.println(m.config.getA());
}
}
@Component
is a generic stereotype annotation which can indicate any of the candidate components i.e; @Repository, @Service, @Controller
and these candidates are eligible for auto-detection.
Where as @Configuration
is used to create component which is used by spring framework to create the application context, internally @Configuration
makes use of @Component
it makes sense reason being even that's a spring component which the framework itself creates.