Questions:
1) Difference between @Component
and @Configuration
?
I have read that both remove the necessity of wiring code to be put in XML, but did not get the difference between these.
2) What are the differences between @Autowired
, @Inject
and @Resource
?
- Which one to use when?
- What are the pros/cons of each?
Spring provides four different types of auto component scan annotations, they are @Component , @Service , @Repository and @Controller . Technically, there is no difference between them, but every auto component scan annotation should be used for a special purpose and within the defined layer.
@Component is a generic stereotype for any Spring-managed component. @Service annotates classes at the service layer. @Repository annotates classes at the persistence layer, which will act as a database repository.
@Component is a generic stereotype for any Spring-managed component or bean. @Repository is a stereotype for the persistence layer. @Service is a stereotype for the service layer. @Controller is a stereotype for the presentation layer (spring-MVC).
@Component
and @Configuration
are indeed very different types of annotations.
@Component
and similar annotations (@Service
, @Repository
, etc. )and its JSR-330 counterpart @Named
allow you to declare beans that are to be picked up by autoscanning with <context:component-scan/>
or @ComponentScan
they register the bean definition for the classes, so they are roughly equivalent to declaring the specified beans with the <bean ... />
tag in XML. This bean types will adhere to the standard proxy creation policies.
@Configuration
annotation was designed as the replacement of the XML configuration file. To create @Configuration
annotated beans, Spring will always use CGLIB
to subclass the @Configuration
annotated class, overriding its @Bean
annotated method to replace it with the bean lookup method to make singleton beans to be created only once. (Spring does not use CGLIB
to intercept internal method calls of normal Spring beans, it creates a separate instance of proxy instead(same way like JDK proxy does). Doing so allows to use proxies to avoid cardinality mismatch - for example a proxy singleton can fetch current session bean, which is not possible with class inheritance only. ). Despite that, @Configuration
annotated classes are still able to use annotated(@Autowired
, @Inject
etc.) fields and properties to request beans (and even other @Configuration
annotated beans too) from the container.
Example from 4.12.5 section of the documentation
@Configuration public class AppConfig { @Bean public ClientService clientService1() { ClientServiceImpl clientService = new ClientServiceImpl(); clientService.setClientDao(clientDao()); return clientService; } @Bean public ClientService clientService2() { ClientServiceImpl clientService = new ClientServiceImpl(); clientService.setClientDao(clientDao()); return clientService; } @Bean public ClientDao clientDao() { return new ClientDaoImpl(); } }
in the example above only one ClientDao
instance will be created.
@Autowired
is Spring annotation, while @Inject
is a JSR-330 annotation. @Inject
is equivalent to @Autowired
or @Autowired(required=true)
, but you can't get @Autowired(required=false)
behavior with the JSR-330 @Inject
annotation. This annotation always uses by-type autowiring.
Spring implements JSR-250 @Resource
annotation in a rather special way. @Resource
was originally designed for locating JNDI resources in Java EE, but Spring widens it applicability making it possible to wire to any bean in the container(JNDI resources are available as beans with the help of SimpleJndiBeanFactory). The name of the corresponding bean can be specified as name
attribute of @Resource
annotation, if no name was specified, then the name of the annotated field or property will be used. Another strange feature is that if no bean with the property name was found spring will fallback to by-type wiring.
Example Imagine that we have an AlphaClass
bean named beanAlpha and a BetaClass
bean beanBeta in the container.
@Resource BetaClass something; // Wires to beanBeta - by-type @Resource BetaClass beanAlpha; // Will throw exception, because "beanAlpha" is not BetaClass -> it's a bad idea to use @Resource as a replacement of @Autowired @Resource Object beanAlpha; //Wires to beanAlpha - by-name
So it's a good practice to always specify resource name explicitly when using @Resource
annotation.
Documentation
Spring annotations
Bean standard annotations
update fixed JSR references as shevchik has pointed out. DI specific annotations are provided by JSR-330, which was developed by Google (Guice Framework) and SpringSource(Spring Framework) engineers. @Resource
is JNDI based and provided by JSR-250.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With