Are #InjectParam (com.sun.jersey.api.core.InjectParam) and #Autowired (org.springframework.beans.factory.annotation.Autowired) same?
In one of the project, I have seen both of these are being used for similar purposes, hence I guess both can do the same job.
I am just wondering if my guess is correct or I am missing some critical catch out there.
I would appreciate if someone can explain the difference and which one to use under what situation?
Thanks.
Both #InjectParam and #Autowired are used for dependecy injection purposes.
According to the documentation, Jersey's #InjectParam is used to annotate fields, methods or parameters that shall be injected with instances obtained from Jersey or registered IoC component provider factories that provide support for Guice, Spring or CDI.
Spring's #Autowired is used to perform injections in the Spring Framework and, as far as I know, it won't work in Jersey resources.
From this post #Autowired not working on jersey resource , it seems #Autowired does not work with Jersey resource in which case we have to use #InjectParam for Jersey resouce.
Related
I downloaded the spring-framework project, because I want to see how #Autowired is implemented.
So, I got to this file, which is an interface.
But when I want in Intellij to go to its implementation, no implementations are found.
So is this interface not implemented?
Then where is the code for #Autowired?
Well, this is not an interface it is actually an annotation.
In java #inteface is used to create an annotation.
Once the annotation is created, you can use that annotation on fields, classes, methods (based on what is specified in #Target of the annotation definition.
Spring does package scanning and finds all the things which are using a particular annotation and does the required processing.
Use this article to undestand more in How an annotation is created, used and the how the annotation processor finds and processes the annotation.
#Autowired doesn't really have much code, so to speak. It's just an annotation which is a Java type of interface that provides instructions to other parts of the codebase.
#Autowired is only an annotation or you can say a "marker". Spring use reflection to identify annotation and do something about that annotated thing. For example with #Autowired, when spring found it, spring will inject the annotated property with eligible bean.
As in the title above, I am confused about pros cons between injecting applicationContext by directly #Autowired annnotation or implementing ApplicationContextAware interface in a singleton spring bean.
Which one do you prefer in which cases and why? Thanks.
Actually, both are bad. Both of them tie your application to the Spring framework, thus inverting the whole inversion-of-control concept. In an ideal world, your application should not be aware of being managed by an ApplicationContext at all.
Once you have chosen to violate this principle, it doesn't really matter how you do it. ApplicationContextAware is the legacy version that has been around at least since Version 2.0. #Autowired is a newer mechanism but they work in pretty much the same way. I'd probably go with ApplicationContextAware, because it semantically makes clear what it is about.
As #Sean Patrick Floyd says, the need of ApplicationContext is often due to a bad design. But sometimes you have no other option. In those cases I prefer the use of #Autowired because is the way I inject all other properties. So, if I use #Autowired for injecting MyRepository, why can't I use it for ApplicationContext or any other Spring bean?
I use Spring interfaces only for those things I can't do with annotations, for example BeanNameAware.
If you need to get a prototype in a singleton then you can use method injection. Basically, you create an abstract method that returns the object you need and spring will return the prototype everytime you call that method. You define the "lookup-method" in your spring config. Here are some links:
http://docs.spring.io/spring/docs/1.2.9/reference/beans.html#beans-factory-method-injection
http://java.dzone.com/articles/method-injection-spring
Since you are not extending any of the spring classes your application is always separated from the framework. Most of the cases you will not wanted to inject the ApplicationContext as it, but will need to inject the beans defined in the ApplicationContext.
The best case is always to stick to the bare minimum, until and unless you have any specific requirement and this is very simple with spring.
So either,
Annotate your beans and scan them in application context, then use #Autowire to wire them up.
Use application context to wire your bean expediencies(old xml style configs). You can use #Autowire with this approach also.
When you want to control the bean life cycle, you can read the API and customize it, but most of the time these general settings will do the job.
Here are some examples.
Spring Auto-Wiring Beans with #Autowired annotation
Spring Auto-Wiring Beans XML Style
Spring IoC container API Docs
There is no need to use ApplicationContext at all.
ObjectFactory
If you need to use prototype scoped beans in a singleton bean, inject an org.springframework.beans.factory.ObjectFactory.
For example using constructor injection:
#Service
class MyClass {
private ObjectFactory<MyDependency> myDependencyFactory;
public MyClass(ObjectFactory<MyDependency> prototypeFactory) {
myDependencyFactory = prototypeFactory;
}
}
Why
Now what's the benefit over using ApplicationContext ?
You can substitute this dependency (e.g. in a test) by simply passing a lambda (since ObjectFactory is a #FunctionalInterface) that returns a stubbed version of it.
While it is possible to stub the ApplicationContext, it is not clear in that case which beans will be looked up and need to be stubbed.
i am just wondering what is the difference between #Inject & #Autowired
when to use each one ?, or they are doing the same thing ?
and if i have a spring bean which have a scope:
#Service
#Scope("singleton")
can i make dependency injection for it with both with no problems ?
thanks in advance.
From what I know, they do the same. #Inject is an annotation from javax.inject, which is only the API for dependency injection. In Spring you can use both, as I think Spring provides an implementation for #Inject which does the same thing as #Autowired in Spring environments.
Matthias Wessendorf blogged about this here: http://matthiaswessendorf.wordpress.com/2010/04/20/spring-3-0-and-jsr-330-part-2/
How about reading the documentation?
JSR 330's #Inject annotation can be used in place of Spring's
#Autowired in the examples below. #Inject does not have a required
property unlike Spring's #Autowired annotation which has a required
property to indicate if the value being injected is optional. This
behavior is enabled automatically if you have the JSR 330 JAR on the
classpath.
I think it is worth pointing out that, if you use #Autowired, you are creating a dependency on Spring, where using #Inject, you will be able to swap out another dependency injection framework that supports JSR 330.
First, #Autowired is defined by Spring Framework but #Inject came from "Dependency Injection for Java" (JSR-330)"
Second, #Inject doesn't take required attribute so if it fails to find any bean, it will fail with an error but #Autowired can come with required=false and will allow a nullable field.
Third, Advantage of #Inject annotation is that rather than inject a reference directly, you could ask #Inject to inject a Provider. The Provider interface enables, among other things, lazy injection of bean references and injection of multiple instances of a bean.
I know this sounds strange, mixing CDI (Weld) and Spring for the controller.
But imagine this situation :
With CDI, i can make use of the #ConversationScoped, which is one of my requirement (And so far i dont know whether i can use spring for this kind of scope, because if i can, i could just replace Weld with Spring, with the el-resolver in faces-config.xml)
My services objects(#Service) along with the DAOs(#Repository) are to be managed by Spring
Now one question arise is that, inside my controller, how can i access my service object ?
Something like this wouldnt work i think :
#Named
#ConversationScoped
public class MyBean {
#Named
private SomeOtherBeanManagedByCDI myOtherBean; // this will work
#Autowired
private MySpringBean mySpringBean; // dont think that this will work
....
}
Any ideas on how to make use of spring beans inside a cdi bean ? Thank you !
update
I've just tested the solution from this article, and so far it works fine, and i feel relieved.
Thank you !
Rick Hightower wrote a nice Extension library which supports to inject Spring beans into CDI beans and vice versa:
http://rick-hightower.blogspot.com/2011/04/cdi-and-spring-living-in-harmony.html
There is still a good accepted answer and some good edits in the OP, but I think there still is time to point out the Seam Spring module.
Also, if you're trying to manage state across a series of pages, and want the effective of conversation management for Struts or JSF or Spring MVC, Spring Web Flow provides just what you need, complete with flow-scoped beans that live for the duration of a flow, more or less equivalent to a conversation in Seam / CDI. If you want a more long lived flow managment solution, the Activiti SPring module makes it dead simple to configure some beans that live for the duration of the process scope, akin to the functionality that Seam had for jBPM.
I have my business bean defined thus:
#Local
#Interceptors(BusinessInterceptor.class})
public class MyBean implements SomeBean { ... }
And then I want my BusinessInterceptor to be configured with Spring's SpringBeanAutowiringInterceptor:
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class BusinessInterceptor {
#Autowired
private SomeSpringBean someSpringBean;
}
Is this allowed/legal? I'm getting errors (NPEs, mostly) suggesting that the fields in BusinessInterceptor have not been initialized properly.
I doubt this can work. If I understand well your scenario, you have basically two DI containers, one is Spring and the other the app. server itself. Each one manages different elements. The BusinessInterceptor is created by the app. server which is unaware of Spring -- the #Autowired bean is then not set.
( Note that Spring and EJB3 have become quite similar now. You can have the same functionalities as EJB with Spring. Spring has indeed declarative transactions, dependency injection and AOP facilities similar to EJB3 interceptors (these are the main managed features). On the other hand, EJB3 is now so lightweight that there isn't really a compelling reason to use Spring with with EJB3. See Future of enterprise Java: full stack Spring or full stack Java EE. But this does not answer the question, and is just a little digression of mine :)