I have an interface its 2 implementation. I annotate both implementations by #Component. How can I specific one of them to be the default bean when will be used to inject by #Autowired as default.
Thanks
Use #Primary annotation on the bean which you think given higher priority.
from doc
Indicates that a bean should be given preference when multiple
candidates are qualified to autowire a single-valued dependency. If
exactly one 'primary' bean exists among the candidates, it will be the
autowired value.
May be used on any class directly or indirectly annotated with
Component or on methods annotated with Bean.
Using Primary at the class level has no effect unless
component-scanning is being used. If a Primary-annotated class is
declared via XML, Primary annotation metadata is ignored, and <bean
primary="true|false"/> is respected instead.
Autowired works "by type", meaning it can autowire when exactly one bean matches. When more than one bean matches, use Autowired + Qualifier annotations. Qualifier calls out the name of the bean to autowire.
This means when you declare the Components you need to name them as well.
Related
So, if I understood correctly, both are the way to determine which bean to autowire if there are multiple candidates. So what exactly is the difference?
Read #Primary as the "default".
If a bean has #Autowired without any #Qualifier, and multiple beans of the type exist, the candidate bean marked #Primary will be chosen, i.e. it is the default selection when no other information is available, i.e. when #Qualifier is missing.
A good use case is that initially you only had one bean of the type, so none of the code used #Qualifier. When you then add another bean, you then also add #Qualifier to both the old and the new bean, so any #Autowired can choose which one it wants. By also adding #Primary to the old original bean, you don't have to add #Qualifier to all the existing #Autowired. They are "grandfathered" in, so to speak.
#Primary is also good if e.g. 95% of #Autowired wants a particular bean. That way, only the #Autowired that wants the other bean(s) need to specify #Qualifier. That way, you have primary beans that all autowired wants, and #Qualifier is only used to request an "alternate" bean.
#Qualifier should be used in conjuction with #Autowired always. This will indicate the bean name which needs to be Autowired in case of multiple beans with same type is present in the application context.(so that spring can autowire by name.)
#Primary should be used in conjuction with #Bean / #Autowired which indicates which bean should be given higher preference, when there are multiple beans of same type is present.
One of the classic use cases where you would use #Primary is when the framework(example spring-data) expects a bean of some type (example EntityManager) but you have multiple datasources and you would have configured multiple Entity Managers. In such cases #Qualifier doesn't quite help.
#Qualifier
If there are more than one instances available for an injection point then we can use #Qualifier annotation to resolve an ambiguity. As #Qualifier is used at the injection point, there might be two situations where we don't want to or cannot use #Qualifier.
When autowiring mode is Autowire.BY_TYPE. Then, of course, we cannot use #Qualifier because we actually don't have user-defined injection point specified as #Autowired or #Inject
We want to do bean selection (i.e. resolve the ambiguity) at
configuration time rather than during beans development time.
The solution to above problems is to use #Primary annotation.
#Primary
This Indicates that a particular bean should be given preference when multiple beans are candidates to be autowired to a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value.
What does it mean when Weld says "unsatisfied dependency for type Foo" when the bean is POJO but, as soon as I add #Dependent at the top, everything works ok?
I remember it used to work fine without specifying the scope. I think I broke something.
The specs say:
A managed bean is implemented by a Java class, which is called its bean class. A top-level Java class is a managed bean if it is defined to be a managed bean by any other Java EE technology specification, such as the JavaServer Faces technology specification, or if it meets all the following conditions.
It is not a nonstatic inner class.
It is a concrete class or is annotated #Decorator.
It is not annotated with an EJB component-defining annotation or declared as an EJB bean class in ejb-jar.xml.
It has an appropriate constructor. That is, one of the following is the case.
The class has a constructor with no parameters.
The class declares a constructor annotated #Inject.
No special declaration, such as an annotation, is required to define a managed bean.
Sounds like you were used to CDI 1.0 and are now confused by implicit bean archives introduced in CDI 1.1.
beans.xml is now optional, and implicit bean archives are the default, which means that a class is a bean candidate only if it has a bean defining annotation like #Dependent, #RequestScoped etc.
So my question why did #javax.annotation.Resource worked but #AutoWired did not. For a test on a Restful controller, I was trying to inject MappingJackson2HttpMessageConverter with #Autowired, on start up the container failed to find a qualifying bean even though that class was on the path. Now, to solve this I went into a context xml file and added the bean:
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
Then in the test class had member variable:
#javax.annotation.Resource(name="jsonConverter")
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;
Then spring finds the bean. Does Autowire only work for beans that were identified as beans by package scan?
Thanks ahead of time.
Autowired and Resource merely make the class types of annotated field, method or constructor eligible for dependency injection - it does not automatically add those types to the context of your Spring application!
So, as you suspect, in order for the annotations to work, you have to ensure that the auto-wired types are available in the application context yourself, e.g. with the Component annotation and package scan or by explicitly defining the bean in your application-context.xml as you did in your example.
In both cases Spring wires the dependency only when the bean getting wired is defined into spring context. You have to either define the bean in xml file or use annotation based bean definition to make it eligible for wiring.
On the other note, #Resource does name based wiring whereas #Autowire by default goes with type based.
Please see #Resource vs #Autowired for more context on topic.
This is from Spring reference. The second para may provide pointers.
If you intend to express annotation-driven injection by name, do not
primarily use #Autowired, even if is technically capable of referring
to a bean name through #Qualifier values. Instead, use the JSR-250
#Resource annotation, which is semantically defined to identify a
specific target component by its unique name, with the declared type
being irrelevant for the matching process.
As a specific consequence of this semantic difference, beans that are
themselves defined as a collection or map type cannot be injected
through #Autowired, because type matching is not properly applicable
to them. Use #Resource for such beans, referring to the specific
collection or map bean by unique name.
#Autowired applies to fields, constructors, and multi-argument
methods, allowing for narrowing through qualifier annotations at the
parameter level. By contrast, #Resource is supported only for fields
and bean property setter methods with a single argument. As a
consequence, stick with qualifiers if your injection target is a
constructor or a multi-argument method.
I think, in your case, there could be some issue with the default autowiring by name. So I guess Spring would be able to #Autowire the bean if you mention the qualifier. But then again if it is a case for #Resource, I think I'd prefer using it.
Is there anyway to specify order in which beans to be instantiated? i.e. I want specific beans to be instantiated before other beans, its like startup sequence.
I am using Spring 3.2 and annotation based declaration method.
If bean A depends on bean B by defining <property/>, #Autowired or <constructor-arg/> then the order is forced and fixed by the Spring container. No problem here.
But if you want to enforce specific order of bean creation which is not expressed via explicit dependencies feel free to use:
<bean id="A" depends-on="B"/>
<bean id="B"/>
or better (with annotations, works also with #Bean Java configuration):
#Service
#DependsOn("B")
public class A {}
or even better... don't use it. These constructs are a code smell and often suggest you have some nasty invisible dependency between your components.
Agreed with the answer provided by Tomasz. If you know that bean A depends on bean B then this is right approach.
Sometimes you have logic that should be executed before all beans instantiation. In this case you can use BeanFactoryPostProcessor. Spring creates and executes BeanFactoryPostProcessors first and after that only all other beans. At the same time if your BeanFactoryPostProcessor depends on some bean A you can use property or constructor injection. In this case Spring will create bean A first, then your BeanFactoryPostProcessor, call BeanFactoryPostProcessor and after that only instatiate all other beans in the context.
You can use the Ordered interface on your bean to define ordering relative to other beans.
Further,if you use BeanFactoryPostProcessor as emamedov said, Ordered interface can be implemented to control BeanFactoryPostProcessor instance sequence.
Injecting bean with scope prototype with #Autowired usually doesn't work as expected. But when writing code, it's easy to accidentally inject a prototype.
Is there a way to get a list of all #Autowired fields and methods and to match that with a Spring AppContext to check for this?
One approach could be to override org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor(which is responsible for processing #Autowired, #Inject, #Resource etc) and perform the checks that you have mentioned in this overridden bean post processor. However, AutowiredAnnotationBeanPostProcessor gets registered with quite a few of the common custom namespaces (context:component-scan, context:annotation-config etc), so these custom annotations will have to be replaced with the corresponding bean variation and the overridden post processor also registered as a bean.