Disclaim: This post is a collection of information found online.
A Bean can be injected by the following methods:
- Injecting by type: If there's only one bean instance available to be injected to the injection target point then it will injected successfully by type.
- Injecting by name: If there are more than on instance of the same type available for a target injection point then there's a conflict (ambiguity). Spring doesn't known which particular instance to be injected in that case. If the name of parameter is same as bean provider method (the factory method) name then the dependency is resolved by name. The bean provider method can provide a different name than the method name by using @Bean(name=...), the injection point method's parameter name should match in that case as well.
- Injecting by bean's name with matching @Qualifier: If there's an ambiguity then it can also be resolved if the injection point method parameter add a @Qualifier annotation with matching target bean's name.
- Injecting by matching @Qualifiers: Ambiguity can also be resolved by using @Qualifier on the both sides. This is important when a bean provider method has already indented to be exposed as a @Qualifier per business logic sense, so that a particular bean's implementation can be changed without updating all injection points.
By default, Spring injects beans by type. If there are multiple beans with the same type, then injection by name will be used the fallback approach. Here is the quote from the Spring documentation
For a fallback match, the bean name is considered a default qualifier value. Thus, you can define the bean with an id of main instead of the nested qualifier element, leading to the same matching result. However, although you can use this convention to refer to specific beans by name, @Autowired is fundamentally about type-driven injection with optional semantic qualifiers. This means that qualifier values, even with the bean name fallback, always have narrowing semantics within the set of type matches. They do not semantically express a reference to a unique bean id. Good qualifier values are main or EMEA or persistent, expressing characteristics of a specific component that are independent from the bean id, which may be auto-generated in case of an anonymous bean definition such as the one in the preceding example.
@Autowired can be seen as an instruction to Spring framework to automatically create the desired bean. This is the injection part of a dependency injection framework. @Autowired annotation can be applied to
- Setter method
- Config methods: Config methods may have an arbitrary name and any number of arguments; each of those arguments will be autowired with a matching bean in the Spring container. Bean property setter methods are effectively just a special case of such a general config method. Such config methods do not have to be public.
Here is an example of config method:
@Component annotation indicates that an annotated class is a "component". Such classes are considered as candidates for auto-detection when using annotation-based configuration and classpath scanning. The class annotated with @Component can be auto-detected. The @Component annotation marks a java class as a bean so the component-scanning mechanism of spring can pick it up and pull it into the application context.
What is the difference between @Component and @Bean?
@Component and @Bean do two quite different things, @Component (and @Service and @Repository) are used to auto-detect and auto-configure beans using classpath scanning. There's an implicit one-to-one mapping between the annotated class and the bean (i.e. one bean per class). Control of wiring is quite limited with this approach, since it's purely declarative.
@Bean is used to explicitly declare a single bean, rather than letting Spring do it automatically as above. It decouples the declaration of the bean from the class definition, and lets you create and configure beans exactly how you choose.
Here are more notes:
- @Component auto detects and configures the beans using classpath scanning whereas @Bean explicitly declares a single bean, rather than letting Spring do it automatically.
- @Component does not decouple the declaration of the bean from the class definition where as @Bean decouples the declaration of the bean from the class definition.
- @Component is a class level annotation where as @Bean is a method level annotation and name of the method serves as the bean name.
- @Component need not to be used with the @Configuration annotation where as @Bean annotation has to be used within the class which is annotated with @Configuration.
- We cannot create a bean of a class using @Component, if the class is outside spring container whereas we can create a bean of a class using @Bean even if the class is present outside the spring container.
- @Component has different specializations like @Controller, @Repository and @Service whereas @Bean has no specializations.
@Configuration vs @Configurable
@Configuration as a replacement to the XML based configuration for configuring spring beans. So instead of an xml file we write a class and annotate that with @Configuration and define the beans in it using @Bean annotation on the methods.
@Configurable is an annotation that injects dependencies into objects that are not managed by Spring using aspectj libraries. We still need to use the old way of instantiation with plain new operator to create objects but the spring will take care of injecting the dependencies into that object automatically.
We use @ComponentScan annotation along with @Configuration annotation to specify the packages that we want to scan.
----- END -----
©2019 - 2021 all rights reserved