将Spring JpaRepository集成到JAX-RS(Jersey)应用时出现空指针异常
问题分析
你的核心问题是Jersey(JAX-RS)资源类SecurityController由Jersey容器实例化,而非Spring容器,导致Spring管理的TlRoleRepository无法被注入,最终调用findAll()时触发NullPointerException。
解决方案
1. 整合Spring与Jersey容器
首先需要让Jersey能够识别Spring管理的Bean,引入Spring-Jersey整合依赖:
<!-- 如果是Spring Boot项目 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jersey</artifactId> </dependency> <!-- 如果是纯Wildfly+Jersey项目,使用对应版本的Jersey-Spring依赖 --> <dependency> <groupId>com.sun.jersey.contribs</groupId> <artifactId>jersey-spring</artifactId> <version>与你的Jersey版本匹配</version> </dependency>
2. 让Jersey资源类由Spring管理
方式一:标记资源类为Spring组件
在SecurityController上添加@Component注解,同时修改JAX-RS启动类ApplicationEntry,注册Spring管理的Bean:
@ApplicationPath("/api") public class ApplicationEntry extends ResourceConfig { @Autowired private ApplicationContext springContext; public ApplicationEntry() { // 注册Spring托管的控制器实例 register(springContext.getBean(SecurityController.class)); // 或者扫描指定包下的Spring组件 packages("com.your.package.controller"); // 启用Spring与Jersey的桥接 register(SpringComponentProvider.class); } }
方式二:通过Jersey注入Spring Bean
如果不想让控制器完全由Spring托管,可在TlRoleRepository上保留@Repository注解,然后在SecurityController中使用@Inject注入,并确保Jersey配置了SpringComponentProvider。
3. 验证Spring JPA配置正确性
确保TlRoleRepository正确继承JpaRepository,且Spring配置类开启JPA仓库扫描:
@Configuration @EnableJpaRepositories(basePackages = "com.your.package.repository") @EntityScan(basePackages = "com.your.package.entity") public class JpaConfig { // 若Wildfly未提供容器管理的数据源,需手动配置DataSource、EntityManagerFactory }
4. 处理Wildfly容器依赖冲突
Wildfly 31默认自带JPA实现(Hibernate),若你使用EclipseLink,需排除容器自带模块避免冲突,在jboss-deployment-structure.xml中配置:
<jboss-deployment-structure> <deployment> <exclude-subsystems> <subsystem name="jpa" /> </exclude-subsystems> <exclusions> <module name="javax.persistence.api" /> <module name="org.hibernate" /> </exclusions> </deployment> </jboss-deployment-structure>
5. 调试验证
在SecurityController构造方法中添加日志,确认实例化来源:
@Path("/roles") @Component public class SecurityController { @Autowired private TlRoleRepository tlRoleRepository; public SecurityController() { System.out.println("SecurityController实例化类加载器:" + this.getClass().getClassLoader()); } @GET @Produces(MediaType.APPLICATION_JSON) public List<TlRole> getAllRoles() { return tlRoleRepository.findAll(); } }
若输出的类加载器为Spring相关,则说明Spring已接管实例化,注入应正常生效。
内容的提问来源于stack exchange,提问作者spirit
相关产品推荐
相关产品推荐

