Combining Spring project and Jersey

风格不统一 提交于 2019-12-16 22:51:11

问题


I've built a project with Spring JPA, and now I want to use it in my Jersey project. I've added my SJPA project as a dependency in my pom.xml

I would like to use my service classes from my SJPA when I use GET/POST/PUT/DELETE methods. Is there an easy way to do this with annotations? Or do I have to get AnnotationConfigApplicationContext in each class? Feels kind of waste.

@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public final class UserResource
{
    private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    private PodcastService service;

    @GET
    public Response getAllPodcasts() {
        context.scan("org.villy.spring.service");
        context.refresh();
        service= context.getBean(PodcastService.class);
        return Response.ok(service.findAll()).build();
    }
}

回答1:


NOTE: The linked example projects below are from the Jersey master branch, which is currently a snapshot of Jersey 3, which is not yet released. Jersey 3 will be using Spring 4, so you may notice a dependency jersey-spring4. This dependency does not exist yet, as Jersey 3 is not yet released (probably not for a while). So the dependency to use is jersey-spring3. All the example should still work the same, just changing that one dependency. If you want to use Spring 4, see the dependencies listed in the example pom below in this answer


You don't need to create the ApplicationContext where you need the service. You should be able to configure a global one. Jersey has a module for this that integrates the two frameworks. This allows you to simply @Autowired all your Spring services into your Jersey resource classes.

Instead of trying to produce any example, I will just link to the official examples. They are straight from the projects, so the links should be good for some time. Take special not of the Maven dependencies. You will need to make sure to have them for the example to work.

  • Jersey 2.x with Spring XML config
  • Jersey 2.x with Spring Java config [1]
  • Jersey 1.x with Spring XML config
  • Jersey 2.x with Spring Boot

Note: The ${spring3.version} version in the examples is 3.2.3.RELEASE. It's possible to use Spring 4 with the examples, but you will need to make sure to exclude all the Spring transitive dependencies from the jersey-spring3 dependency.

[1] - One thing to note about the Java config example is that it uses a standalone app. To use Java config in a webapp requires a bit of trickery. This is a known bug where Jersey looks for an param contextConfigLocation with the location of the applicationContext.xml file and will throw an exception when it doesn't find one.

I've found a few ways around this.

  1. An example of this was mentioned by the person who raised the issue. You can create a Spring web initializer where you configure the spring context and override the param property. (See full example here).

    @Order(1)
    public class SpringWebContainerInitializer implements WebApplicationInitializer {
    
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            registerContextLoaderListener(servletContext);
    
            // Set the Jersey used property to it won't load a ContextLoaderListener
            servletContext.setInitParameter("contextConfigLocation", "");
        }
    
        private void registerContextLoaderListener(ServletContext servletContext) {
            WebApplicationContext webContext;
            webContext = createWebAplicationContext(SpringAnnotationConfig.class);
            servletContext.addListener(new ContextLoaderListener(webContext));
        }
    
        public WebApplicationContext createWebAplicationContext(Class... configClasses) {
            AnnotationConfigWebApplicationContext context;
            context = new AnnotationConfigWebApplicationContext();
            context.register(configClasses);
            return context;
        }
    }
    
  2. You could simply add the applicationContext.xml to the classpath and just register the spring Java configuration class as a bean

    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">
    
    
        <context:annotation-config/>
        <bean id="config" class="com.your.pkg.SpringAnnotationConfig"/>
    
    </beans>
    
  3. There's another way I can think of, but I've save that for a time I can actually test it out.


UPDATE

"Failed to read candidate component class ... ASM ClassReader failed to parse class file - probably due to a new Java class file version that isn't supported yet"

Seems to be related to this, using Spring 3 with Java 8. Like I said, if you want to use Spring 4, you will need to exclude the Spring transitive dependencies from jersey-spring3 and just change the version of your explicitly declared Spring dependencies. Here is an example, that I tested and works.

<dependency>
    <groupId>org.glassfish.jersey.ext</groupId>
    <artifactId>jersey-spring3</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId> 
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId> 
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId> 
        </exclusion>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId> 
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.1.0.RELEASE</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.1.0.RELEASE</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.1</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.1</version>
</dependency>


来源:https://stackoverflow.com/questions/32355845/combining-spring-project-and-jersey

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!