How to use Jersey 2 with Spring IoC container - spring

What is the best way to enable injection of spring beans into Jersey 2? Jersey seems to not support this natively.
What is needed to wire the 2 frameworks together? In pom.xml and web.xml?

Jersey 2.3 has now spring support:
https://jersey.github.io/documentation/latest/user-guide.html#spring
As stated in the documentation
The Spring extension module configuration is based on annotations
So you have to tell spring to scan your classpath, for example:
<context:component-scan base-package="my.package.to.resources">
and annotate your resource class with a spring annotation (I advise to use #Component, and then specify the jersey resource scopes #Singleton/#PerLookup/#RequestScoped )
#Component
#Singleton
#Path("example")
public class Example {
//Spring beans can't be injected directly into JAX-RS classes by using Spring XML configuration
#Autowired
private MyOtherBean myOtherBean;
#GET #Path("hello")
public String hello() {
return myOtherBean.hello();
}
}

As of June 2013, Jersey 2.0 has no official Spring support. There are two options:
Use third party code from here https://github.com/marko-asplund/jersey/tree/master/ext/jersey-spring
Wait until HK2 spring bridge becomes stable and documented https://java.net/jira/browse/HK2-40
See also:
http://jersey.576304.n2.nabble.com/Spring-framework-support-for-Jersey-2-td7580673.html
EDIT: Jersey 2.3 has spring support now, see the answer by Fabio below

You should be able to annotate jersey components and then use annotations to inject the beans.
#Service //(or #Component)
public class MyJerseyService {
#Autowired
private MyObj mySpringBean
}

Related

Spring boot jersey - prevent startup instantiation of controller

I am using spring boot with web and jersey (spring-boot-jersey-starter). I have a Jersey endpoint that needs to inject a request scope bean. However, at startup of the application I am getting a no bean found error.
#Component
#Path("blah")
#RequestScoped
public class JerseyController{
#Inject
private MyEntity entity;
}
#Component
public class JerseyConfiguration extends ResourceConfig{
public JeyseyConfiguration(){
register(JeyseyController.class);
registere(MyEntityProvider.class);
}
}
Is there a way, in a spring-boot web app, to prevent Spring from attempting to instantiate and inject my JerseyController until an HTTP request is received so that the injected dependency can be provided by my Jersey provider?
#Component is not required on Jersey resources. Having it will cause Spring to instantiate it (with default Singleton scope). I don't think Spring doesn't respect the #RequestScoped. This is a Jersey annotation. If you want to use the #Component, I think the Spring #Scope("request") might do the trick though.
You can also remove the #RequestScoped. This is the default scope for Jersey resources.
The only time I have ever found a need to use #Component on Jersey resources, is if I need to use the Spring #Value (maybe AOP also, but I don't do much AOP). Other than that, the Jersey-Spring integration already supports the most common used feature of Spring which is DI. And if you really want to make the Jersey resource a singleton, Jersey supports the #Singleton annotation.

Purpose of using #Configuration annotation

I have created a spring mvc based application but I didn't use this #Configuration annotation. What is the purpose of using #Configuration annotation? By using this, what are we communicating to springMVC container?
Assuming your application is using xml configuration rather than AnnotationConfig so it is not loaded to ApplicationContext at all.
#Configuration is used when ApplicationContext has been initialized and bean registration.
#Configuration annotation is a core Spring annotation, and not Spring MVC. It is a core entry point to configuring Spring-based application using Java config instead of XML config.
Please, use Spring Documentation more often because it is a place where you will find answers to most of your questions. Like this one:
Indicates that a class declares one or more Bean #Bean methods and may
be processed by the Spring container to generate bean definitions and
service requests for those beans at runtime

Possible to autowire imported utility classes in Spring?

I want to use data mappers, logger, transfromers, etc. in my Spring web projects. Is it possible to autowire an imported (jar) utility dependency, without wrapping it in some #Component or #Service class? Do we even want to do it that way, or should we just use a static reference?
If your utils, are based on not static methods, then this is simple:
If you use java based configuration, then just declare that util in an #Bean annotated method.
#Configuration
public class YourConfig {
#Bean
public YourUtil util(){
return new YourUtil ();
}
}
in xml it could been as simple as:
<bean id="util" class="org.example.YourUtil" />
The following is true, but it is not what was asked for:
There are at least two other ways to inject beans in instances that are not created (managed) by Spring:
(1) add #Configurable annotation to this class - this requires real AspectJ (compile-time or load-time -weaving)
#see Spring Reference Chapter 7.8.1 Using AspectJ to dependency inject domain objects with Spring
#see this answer of mine https://stackoverflow.com/a/7007572/280244 for a quick "guide" to enable the #Configurable support
(2) invoke SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
#see this question and its (two highes voted answers) for some ideas how to use
You can only #Autowire a bean managed by Spring. So you have to declare your instance through some configuration : a bean in an xml file, or a #Bean method in a java configuration.
#Component are just automatically discovered and registered in the spring context.

Integrate Spring in Jax-RS

Is it possible to intergrate Spring in JAX-RS-API? We wan't use no implementation of JAX-RS (no imports of Jersey, CXF, etc. in our Java code)
Yes it's possible.
You will define #Path and #Component with jax-rs import.
You will define #Controller with Spring annotation.
The link between both will be made by the applicationContext or by annotation.
So, in my opinion yes, you can.

Integrating Spring XML beans from external jar into a CDI application

I have a new CDI Java EE application running on WebSphere. Now I want to use an existing module (.jar) in my CDI project, however the existing module uses Spring with Spring annotations and an Spring XML configuration file with additional bean definitions in it. Normally I would just import the Spring XML in my project, but in the CDI application this will not work.
I tried to load the Spring XML using JBoss Seam, like so:
#Produces
#SpringContext
#Configuration(locations = "classpath*:external-spring--context.xml")
ApplicationContext context;
But the context is null? I cannot realy find good examples on how to do this, help is much appreciated :)
I solved it by adding an CDI producer that will create the Spring context using the spring XML file:
public class SpringBeansFactory {
#Inject
ApplicationContext context;
#Produces
public BusinesService getBusinessService() {
return context.getBean(BusinesService.class);
}
}
class SpringContextFactory {
#Produces
public ApplicationContext getApplicationContext() {
return new ClassPathXmlApplicationContext("classpath:spring-context.xml");
}
}

Resources