Spring Java项目无@Bean配置下@Autowired注入空指针问题求助
解决Spring @Autowired在JAX-RS资源类中注入失败的问题
你的核心问题很明确:JAX-RS资源类默认由JAX-RS容器管理,而非Spring容器,所以Spring的@Autowired注解无法生效,导致pojoService为null抛出空指针异常。下面是针对你的代码的具体修复方案:
问题根源拆解
你写的Resource类同时标注了JAX-RS的@Path和Spring的@Controller,但默认情况下:
- JAX-RS容器(比如Jersey)会自己实例化
Resource类,不会交给Spring管理 - Spring的依赖注入逻辑只对自己容器内的Bean生效,所以
@Autowired自然无法注入PojoService
解决方案步骤
1. 添加Spring与JAX-RS的整合依赖
假设你使用的是最常用的JAX-RS实现Jersey,需要添加适配Spring 5的整合依赖,同时排除冲突的Spring组件:
<dependency> <groupId>org.glassfish.jersey.ext</groupId> <artifactId>jersey-spring5</artifactId> <version>2.29.1</version> <exclusions> <!-- 排除与你已声明的Spring版本冲突的依赖 --> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </exclusion> </exclusions> </dependency> <!-- 补充spring-web依赖,整合必须 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.7.RELEASE</version> </dependency>
2. 配置Spring上下文初始化
创建一个Servlet监听器,让Web容器启动时加载Spring的注解配置:
package restoverflow; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; @WebListener public class SpringContextInitializer implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(AppConfig.class); // 将Spring上下文绑定到Web容器 sce.getServletContext().addListener(new ContextLoaderListener(context)); } @Override public void contextDestroyed(ServletContextEvent sce) { // 空实现,按需添加资源清理逻辑 } }
3. 修改JAX-RS应用类,使用Spring管理的Bean
修改你的App类,让JAX-RS从Spring上下文中获取资源实例,而不是自己创建:
package restoverflow; import org.springframework.web.context.support.WebApplicationContextUtils; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; import javax.servlet.ServletContext; import java.util.HashSet; import java.util.Set; @ApplicationPath("/") public class App extends Application { @Override public Set<Object> getSingletons() { ServletContext servletContext = getServletContext(); // 从Web容器中获取Spring上下文 AnnotationConfigWebApplicationContext springContext = (AnnotationConfigWebApplicationContext) WebApplicationContextUtils.getWebApplicationContext(servletContext); Set<Object> singletons = new HashSet<>(); // 添加Spring管理的Resource实例到JAX-RS singletons.add(springContext.getBean(Resource.class)); return singletons; } }
4. 调整Resource类的注解
保持@Component让Spring扫描该类,同时保留JAX-RS的注解:
package restoverflow; import javax.ws.rs.GET; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/resource") @Component // 标记为Spring组件 public class Resource { @Autowired private PojoService pojoService; @GET @Produces(MediaType.APPLICATION_JSON) public Pojo getPojo() { return pojoService.getPojo(); } }
验证效果
启动Web容器后访问/resource路径,此时pojoService已经被Spring成功注入,不会再抛出空指针异常,能正常返回JSON格式的Pojo数据。
额外提示
如果你的项目是基于Spring Boot的,会更简洁:只需要引入spring-boot-starter-jersey依赖,用@Component标记JAX-RS资源类,Spring Boot会自动完成所有整合配置,不需要手动写监听器和应用类的逻辑。
内容的提问来源于stack exchange,提问作者user4591830
相关产品推荐
相关产品推荐

