Difference between #Qualifier and #Resource - java

I don’t see any difference between two ways, #Qualifier is always used with #Autowired.
#Autowired
#Qualifier("alpha")
VS
#Resource(name="alpha")
Anyone could let me know the difference? Thanks!

#Autowired can be used alone . If it is used alone , it will be wired by type . So problems arises if more than one bean of the same type are declared in the container as #Autowired does not know which beans to use to inject. As a result , use #Qualifier together with #Autowired to clarify which beans to be actually wired by specifying the bean name (wired by name)
#Resource is wired by name too . So if #Autowired is used together with #Qualifier , it is the same as the #Resource.
The difference are that #Autowired and #Qualifier are the spring annotation while #Resource is the standard java annotation (from JSR-250) . Besides , #Resource only supports for fields and setter injection while #Autowired supports fields , setter ,constructors and multi-argument methods injection.
It is suggested to use #Resource for fields and setter injection. Stick with #Qualifier and #Autowired for constructor or a multi-argument method injection.
See this:
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, prefer 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.

I was facing some issues with #Autowired and then started using #Qualifier and I was finally able to find out the when to use #Autowired with #Qualifier when multiple beans of same type are defined.
Suppose you define 2 beans of same type but different values :
<bean id="appContext1" class="com.context.AppContext">
<constructor-arg value="abc" />
<bean/>
<bean id="appContext2" class="com.context.AppContext">
<constructor-arg value="ABC" />
<bean/>
Then if you just are trying to use #Autowire, then you have to use the same variable name as of the bean name else it will give error as multiple types found.
#Autowired
AppContext appContext;
For the above use case you have to use Qualifier.
#Autowired
#Qualifier("appContext1")
AppContext appContext;
Instead, if you use the variable name same as bean name, you can eliminate the use of #Qualifier.
#Autowired
AppContext appContext1;
I was always using the variable name same as bean name, but accidentally had some other variable name and faced this issue.
Let me know if there are any doubts.

#Autowired is old school Spring. #Resource is the Java EE CDI standard. Spring handles both (as well as #Inject, which is very similar) and does pretty much the same thing in both situations. I would recommend #Resource, #Autowired was made prior to the standard and seems to be supported mostly for backward compatibility.

Related

Constructor bean injection with custom annotation

I would like to inject a bean (lets call it clientStub) into my service bean.
There are two requirements for that:
In order to create the clientStub bean, I need to access the #Client annotation, that carries some important information that are used to lookup the relevant configuration in the properties.
It must support constructor based injection (and #Bean method parameter injection)
Expected usage:
#Autowired
public MyService(
#Client("invoice-manager") InvoiceManagerClientStub clientStub,
SomeOtherBean bean1, ...) {
or
#Bean
MyService myService(
#Client("invoice-manager") InvoiceManagerClientStub clientStub,
SomeOtherBean bean1, ...) {
So I would like to do the same as the #Value annotation e.g. derive the value from the annotation on the parameter (plus some internal lookups).
Unfortunately, the usual BeanFactorys don't seem to be aware of the target's annotations.
Alternatives considered
Using an BeanPostProcessor to inject the values into annotated fields. Well, this is what I'm currently doing, but it doesn't feel right to have an immutable class with a single setter for injection.
Injecting it to a field and then exposing it as a bean or manually invoking the constructor is even worse.
Creating a proxy instance of the injected class. This isn't possible since the injected classes are generated + final and not part of my library.
Derive the configuration from the bean name: Not sure how to implement this and how to explain the user what the configuration parameters should be named in their properties files. I also would like to avoid bean name conflicts.
Non-Goals
Overwriting any core beans. I would like to distribute the extension as a library (spring-boot based), so any excessive replacement of spring internal beans should be avoided.
TLDR
How do I tell spring to resolve the parameter using my annotation's value (resolver)?

Why #Autowired wires by class?

If each bean has name, and we have getBean() method, which receives bean name and in XML config we are also injecting beans by name, then why in Java config we are limited to #Autowired annotation which wires by class?
What is conventional way to inject beans into one configuration from another one? Is it possible to refer bean by name and not use #Qualifier?
UPDATE
I found a way to autowire by name between configurations.
First I autowire entire configuration by class:
#Autowired
MySeparateConfig mySeparateConfig;
Then I just call instantiation method from that bean:
#Bean
MyDependentBean myDependentBean() {
MyDependentBean ans = new MyDependentBean();
ans.setProperty( mySeparateConfig.myNamedBeanInDifferentConfig() );
return ans;
}
Configs are of different classes by definition.
Actually, there are several ways to inject bean by annotation.
given that we have this bean
<bean id="standardPasswordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder" />
and in java class we can use following ways to inject it as far as I know
#Autowired // by type
StandardPasswordEncoder standardPasswordEncoder;
#Autowired
#Qualifier("standardPasswordEncoder") // by bean id
StandardPasswordEncoder standardPasswordEncoder;
javax.annotation.#Resource // by bean id
StandardPasswordEncoder standardPasswordEncoder;
javax.inject.#Inject // by type
StandardPasswordEncoder standardPasswordEncoder;
or use spEL
#Value(#{standardPasswordEncoder}) // by bean id
StandardPasswordEncoder standardPasswordEncoder;
However, I don't know the reason why spring autowired default is by type, either, and also wondering why. I think it's dangerous to autowire by type. Hope this would help you.

Does Spring's autowire attribute in XML override how #Autowired property of the bean is autowired?

It seems not the case. I used to have the notion that XML configurations are meant to override annotations. But when I set autowire="no" in the XML configuration, the bean's #Autowired annotated property still takes effect. I'm no longer sure if XML autowire has anything to do with #Autowired anymore. It's quite counter-intuitive in my opinion.
Can someone point me to a documentation that says something about this?
Here's my example:
<bean class="com.example.Tester"></bean>
<bean class="com.example.ClassToTest" autowire="no"></bean>
public class Tester
{
#Autowired
ClassToTest testSubject;
}
public class ClassToTest
{
#Autowired // I want this not to get autowired without removing this annotation
private OtherDependency;
}
autowire="no" means we have to explicit wire our dependencies using either XML-based configuration or #Autowire and it is default setting.
Auto-wiring by xml configutaion or by annotation means implicitly mapping dependencies using given strategy.
For more details refer here

What is the difference between #Inject and #Autowired in Spring Framework? Which one to use under what condition?

I am going through some blogs on SpringSource and in one of the blogs, author is using #Inject and I suppose he can also use #Autowired.
Here is the piece of code:
#Inject private CustomerOrderService customerOrderService;
I am not sure about the difference between #Inject and #Autowired and would appreciate it if someone explained their difference and which one to use under what situation?
Assuming here you're referring to the javax.inject.Inject annotation. #Inject is part of the Java CDI (Contexts and Dependency Injection) standard introduced in Java EE 6 (JSR-299), read more. Spring has chosen to support using the #Inject annotation synonymously with their own #Autowired annotation.
So, to answer your question, #Autowired is Spring's own annotation. #Inject is part of a Java technology called CDI that defines a standard for dependency injection similar to Spring. In a Spring application, the two annotations works the same way as Spring has decided to support some JSR-299 annotations in addition to their own.
Here is a blog post that compares #Resource, #Inject, and #Autowired, and appears to do a pretty comprehensive job.
From the link:
With the exception of test 2 & 7 the configuration and outcomes were
identical. When I looked under the hood I determined that the
‘#Autowired’ and ‘#Inject’ annotation behave identically. Both of
these annotations use the ‘AutowiredAnnotationBeanPostProcessor’ to
inject dependencies. ‘#Autowired’ and ‘#Inject’ can be used
interchangeable to inject Spring beans. However the ‘#Resource’
annotation uses the ‘CommonAnnotationBeanPostProcessor’ to inject
dependencies. Even though they use different post processor classes
they all behave nearly identically. Below is a summary of their
execution paths.
Tests 2 and 7 that the author references are 'injection by field name' and 'an attempt at resolving a bean using a bad qualifier', respectively.
The Conclusion should give you all the information you need.
To handle the situation in which there is no wiring, beans are available with #Autowired required attribute set to false.
But when using #Inject, the Provider interface works with the bean which means that the bean is not injected directly but with the Provider.
The key difference(noticed when reading the Spring Docs) between #Autowired and #Inject is that, #Autowired has the 'required' attribute while the #Inject has no 'required' attribute.
As of Spring 3.0, Spring offers support for JSR-330 dependency injection annotations (#Inject, #Named, #Singleton).
There is a separate section in the Spring documentation about them, including comparisons to their Spring equivalents.
Better use #Inject all the time. Because it is java configuration approach(provided by sun) which makes our application agnostic to the framework. So if you spring also your classes will work.
If you use #Autowired it will works only with spring because #Autowired is spring provided annotation.
#Autowired annotation is defined in the Spring framework.
#Inject annotation is a standard annotation, which is defined in the standard "Dependency Injection for Java" (JSR-330). Spring (since the version 3.0) supports the generalized model of dependency injection which is defined in the standard JSR-330. (Google Guice frameworks and Picocontainer framework also support this model).
With #Inject can be injected the reference to the implementation of the Provider interface, which allows injecting the deferred references.
Annotations #Inject and #Autowired- is almost complete analogies. As well as #Autowired annotation, #Inject annotation can be used for automatic binding properties, methods, and constructors.
In contrast to #Autowired annotation, #Inject annotation has no required attribute. Therefore, if the dependencies will not be found - will be thrown an exception.
There are also differences in the clarifications of the binding properties. If there is ambiguity in the choice of components for the injection the #Named qualifier should be added. In a similar situation for #Autowired annotation will be added #Qualifier qualifier (JSR-330 defines it's own #Qualifier annotation and via this qualifier annotation #Named is defined).
In addition to the above:
The default scope for #Autowired beans is Singleton whereas using JSR 330 #Inject annotation it is like Spring's prototype.
There is no equivalent of #Lazy in JSR 330 using #Inject.
There is no equivalent of #Value in JSR 330 using #Inject.
#Inject has no 'required' attribute
#Autowired(required=false)
By default the dependency injection for #Autowired must be fulfilled because the value of required attribute is true by default. We can change this behavior by using #Autowired(required=false). In this case if bean is not found for dependency injection, it will not through error.
Please have look at
https://www.concretepage.com/spring/spring-autowired-annotation#required-false
But #Inject doesn’t need (required=false) it will not through error if dependency is not found
The #Inject annotation is one of the JSR-330 annotations collection. This has Match by Type,Match by Qualifier, Match by Name execution paths.
These execution paths are valid for both setter and field injection.The behavior of #Autowired annotation is same as the #Inject annotation. The only difference is the #Autowired annotation is a part of the Spring framework. #Autowired annotation also has the above execution paths. So I recommend the #Autowired for your answer.

What is javax.inject.Named annotation supposed to be used for?

I am trying to understand the javax.inject package and I am not clear what the javax.inject.Named annotation is supposed to be used for. The Javadoc does not explain the the idea behind it.
Javadoc is at http://download.oracle.com/javaee/6/api/javax/inject/Named.html
I am using Spring 3.0 to write some sample programs, by putting #Named on a bean it seems to add it to the bean factory but the Javadoc description is so light I can't tell if that is the standard behavior or Spring specific behavior.
My questions are:
What is the difference between #Named and #Qualifier
How are you supposed to tell the Runtime system a class should be injectable in other classes what's the annotation for that? The equivalent of #Component in Spring?
Update 1 there is an excellent explanation of #Named and #Qualifier at Nice article about #Named and #Qualifier https://dzone.com/articles/java-ee6-cdi-named-components thanks #xmedeko for linking to it the comment below.
Use #Named to differentiate between different objects of the same type bound in the same scope.
#Named("maxWaitTime")
public long maxWaitTimeMs;
#Named("minWaitTime")
public long minWaitTimeMs;
Without the #Named qualifier, the injector would not know which long to bind to which variable.
If you want to create annotations that act like #Named, use the #Qualifier annotation when creating them.
If you look at #Named, it is itself annotated with #Qualifier.
#Inject instead of Spring’s #Autowired to inject a bean.
#Named instead of Spring’s #Component to declare a bean.
Those JSR-330 standard annotations are scanned and retrieved the same way as Spring annotation (as long as the following jar is in your classpath)
Regarding #2, according to the JSR-330 spec:
This package provides dependency
injection annotations that enable
portable classes, but it leaves
external dependency configuration up
to the injector implementation.
So it's up to the provider to determine which objects are available for injection. In the case of Spring it is all Spring beans. And any class annotated with JSR-330 annotations are automatically added as Spring beans when using an AnnotationConfigApplicationContext.
The primary role of the #Named annotation is to define a bean for the purpose of resolving EL statements within the application, usually through JSF EL resolvers. Injection can be performed using names but this was not how injection in CDI was meant to work since CDI gives us a much richer way to express injection points and the beans to be injected into them.

Categories