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

Spring MVC 4中Servlet的@Autowired依赖注入失败,如何实例化MyService?

问题描述

我在基于Spring MVC的应用中实现了一个健康检查Servlet(HealthCheckController),尝试使用@Autowired注解注入MyService类,但该类无法被实例化。相关代码如下:

@WebServlet(name = "myServlet", urlPatterns = "/app2") 
public class HealthCheckController extends HealthCheckServlet{ 
    /** The Constant serialVersionUID. */ 
    private static final long serialVersionUID = 1L; 
    @Autowired 
    private MyService service; 

    /** 
     * method to check healthiness. 
     * 
     * @return true, if is healthy 
     * @throws HealthCheckException the health check exception 
     */ 
    @Override 
    public boolean isHealthy() throws HealthCheckException { 
        try { 
            service.showDetails("12", false,null); 
            System.out.println("True"); 
            return true; 
        } catch (Exception e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } 
        return false; 
    } 
}

想请教下如何正确为该Servlet提供MyService的依赖?

解决方案

嘿,这个问题我之前碰到过,核心原因很明确:你的HealthCheckController是由Servlet容器(比如Tomcat)负责实例化的,不属于Spring容器管理的Bean,所以Spring的@Autowired注解根本没法生效,自然注入不了MyService。给你几个靠谱的解决办法:

方法一:手动从Spring上下文获取Bean

在Servlet的init方法里,通过Spring提供的工具类拿到WebApplicationContext,然后手动获取MyService的实例,就能正常使用了:

@Override
public void init() throws ServletException {
    super.init();
    // 获取Spring的Web上下文
    WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
    // 手动获取MyService实例
    service = context.getBean(MyService.class);
}

⚠️ 注意:要确保MyService类上标注了@Service或@Component注解,并且Spring的配置类(或者XML配置)已经开启了组件扫描,这样Spring才能把MyService纳入容器管理。

方法二:改成Spring MVC原生Controller(推荐)

既然是Spring MVC应用,完全没必要直接继承Servlet,直接改成Spring的Controller就好,这样整个类都由Spring管理,@Autowired就能正常工作了,还更符合Spring的架构设计:

@RestController
@RequestMapping("/app2")
public class HealthCheckController {
    @Autowired
    private MyService service;

    @GetMapping
    public ResponseEntity<String> checkHealth() {
        try {
            service.showDetails("12", false, null);
            return ResponseEntity.ok("Healthy");
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("Unhealthy");
        }
    }
}

这种方式不仅解决了依赖注入的问题,还能利用Spring MVC的各种特性,比如统一异常处理、请求参数解析等,非常推荐。

方法三:使用@Configurable(不推荐)

给HealthCheckController加上@Configurable注解,然后配置AspectJ编译时织入,让Spring接管Servlet的实例化。但这个配置比较复杂,需要额外引入AspectJ依赖,而且Servlet容器和Spring的生命周期容易出现冲突,一般不建议这么做。

最后再提醒下:不管用哪种方法,都要确保MyService已经被Spring正确扫描并实例化,不然就算拿到上下文也获取不到Bean哦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:17:02