You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非Spring Boot/SpringRest环境下Spring 5 MVC集成Jersey 2.x及Autowired问题求助

Spring 5 MVC + Jersey 2.x 完整整合示例(解决@Autowired Null问题)

Hey there, let's fix that frustrating @Autowired null issue you're facing! The root cause almost always boils down to Jersey not using Spring's bean container to manage its resources—so let's walk through a step-by-step integration that ensures proper dependency injection works as expected.


1. Core Dependency Setup (Maven)

First, make sure you have the right dependencies in your pom.xml. The key here is the jersey-spring5 module, which bridges Jersey and Spring 5, plus we'll exclude conflicting Spring dependencies from Jersey's package to avoid version mismatches.

<dependencies>
    <!-- Spring 5 MVC Core -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.24</version>
    </dependency>

    <!-- Jersey 2.x Core -->
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.41</version>
    </dependency>

    <!-- Critical: Jersey-Spring 5 Integration -->
    <dependency>
        <groupId>org.glassfish.jersey.ext</groupId>
        <artifactId>jersey-spring5</artifactId>
        <version>2.41</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

2. Web.xml Configuration

We need to configure both Spring's DispatcherServlet (for MVC) and Jersey's ServletContainer (for API endpoints), making sure they use the same Spring context.

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- Spring MVC DispatcherServlet -->
    <servlet>
        <servlet-name>springMvcDispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring-mvc-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMvcDispatcher</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <!-- Jersey Servlet (handles API requests) -->
    <servlet>
        <servlet-name>jerseyServlet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.yourpackage.config.JerseyConfig</param-value>
        </init-param>
        <!-- Key: Tell Jersey to use Spring's existing context -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring-mvc-config.xml</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>jerseyServlet</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>

</web-app>

3. Spring MVC Configuration (spring-mvc-config.xml)

Enable component scanning for your services and controllers, and turn on Spring MVC's annotation support.

<?xml version="1.0" encoding="UTF-8"?>
<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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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
                           http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- Scan for Spring-managed beans (services, MVC controllers) -->
    <context:component-scan base-package="com.yourpackage.service, com.yourpackage.mvc.controller"/>

    <!-- Enable Spring MVC annotation-driven features -->
    <mvc:annotation-driven/>

</beans>

4. Jersey Configuration Class

Create a ResourceConfig subclass to register Jersey's Spring component provider and scan for your Jersey API resources.

package com.yourpackage.config;

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.spring5.SpringComponentProvider;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        // Critical: Register Spring component provider to wire dependencies
        register(SpringComponentProvider.class);
        // Scan for Jersey resource classes in your API package
        packages("com.yourpackage.jersey.resource");
    }
}

5. Example Service & Jersey Resource

UserService Interface & Implementation

package com.yourpackage.service;

public interface UserService {
    String getUserNameById(Long id);
}
package com.yourpackage.service.impl;

import com.yourpackage.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Override
    public String getUserNameById(Long id) {
        return "User_" + id;
    }
}

Jersey Resource with @Autowired

package com.yourpackage.jersey.resource;

import com.yourpackage.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/users")
public class UserResource {

    // @Autowired will now work because Jersey uses Spring's container
    @Autowired
    private UserService userService;

    @GET
    @Path("/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public String getUser(@PathParam("id") Long id) {
        // No more null pointer here!
        return "{\"name\": \"" + userService.getUserNameById(id) + "\"}";
    }
}

Key Fixes for the Null @Autowired Issue

  • Use jersey-spring5: This module is non-negotiable—it connects Jersey to Spring's application context.
  • Share the Spring Context: Ensure Jersey's servlet uses the same contextConfigLocation as Spring MVC, so both use the same bean container.
  • Register SpringComponentProvider: This tells Jersey to delegate bean creation and dependency injection to Spring.
  • Avoid Duplicate Scanning: Make sure your Jersey resources aren't scanned by both Spring's component-scan and Jersey's packages—this can create two instances (one managed by Spring, one by Jersey, which won't have injected dependencies).

Once you set this up, fire up your app and hit http://localhost:8080/your-app/api/users/1—you'll get a valid JSON response, and your UserService will no longer be null!

内容的提问来源于stack exchange,提问作者Dima Shtef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:45:48