Spring Data MongoDB结合Play Framework与Guice时@Autowired注入失效报NullPointerException的解决求助
我懂这种在两个框架整合时踩依赖注入坑的烦躁——Spring Data MongoDB的简洁性确实让人爱不释手,但和Play Framework搭起来时,@Autowired突然罢工抛出NullPointerException真的头大。下面我给你一步步拆解解决方案,帮你搞定这个问题:
第一步:先确保Spring与Play Framework的基础整合配置正确
如果Spring和Play的上下文没打通,@Autowired肯定会失效,先把基础配置做扎实:
- 首先在Play的
build.sbt中添加必要依赖,替换成对应版本:
libraryDependencies ++= Seq( "org.springframework.data" % "spring-data-mongodb" % "3.4.5", "org.springframework" % "spring-context" % "5.3.20", "javax.inject" % "javax.inject" % "1" )
- 创建Spring配置类
SpringConfig.java,用来扫描你的Repository和业务类:
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; @Configuration @ComponentScan(basePackages = "com.yourproject") // 替换成你的项目根包路径 @EnableMongoRepositories(basePackages = "com.yourproject.repository") // MongoDB Repository所在包 public class SpringConfig { }
- 实现Play的
Module接口,把Spring上下文接入Play的Guice容器:
import com.google.inject.AbstractModule; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class SpringModule extends AbstractModule { @Override protected void configure() { // 初始化Spring注解驱动的上下文 ApplicationContext springContext = new AnnotationConfigApplicationContext(SpringConfig.class); // 将Spring上下文绑定到Play的Guice容器中 bind(ApplicationContext.class).toInstance(springContext); } }
- 最后在
conf/application.conf里注册这个Module:
play.modules.enabled += "com.yourproject.SpringModule"
第二步:解决
@Autowired空指针问题 Play默认用Guice做依赖注入,直接在Play管理的类(比如Controller)里用Spring的@Autowired是不生效的,你有两种优雅的解决方式:
方式一:通过Spring上下文手动获取Bean
如果不想改动太多现有代码,可以直接从Spring上下文取出需要的Repository或服务类:
import org.springframework.context.ApplicationContext; import javax.inject.Inject; import play.mvc.Controller; import com.yourproject.repository.YourMongoRepo; public class DemoController extends Controller { private final YourMongoRepo mongoRepo; @Inject public DemoController(ApplicationContext springContext) { // 从Spring上下文获取Bean实例 this.mongoRepo = springContext.getBean(YourMongoRepo.class); } // 现在mongoRepo可以正常调用方法了 }
方式二:让Guice直接注入Spring管理的Bean
更优雅的方式是把Spring的Bean暴露给Guice,修改SpringModule.java:
import com.google.inject.AbstractModule; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.yourproject.repository.YourMongoRepo; public class SpringModule extends AbstractModule { @Override protected void configure() { ApplicationContext springContext = new AnnotationConfigApplicationContext(SpringConfig.class); bind(ApplicationContext.class).toInstance(springContext); // 把需要注入的Spring Bean绑定到Guice容器 bind(YourMongoRepo.class).toInstance(springContext.getBean(YourMongoRepo.class)); } }
之后就可以在Play的Controller里用Guice的@Inject直接注入Spring的Repository了:
import javax.inject.Inject; import play.mvc.Controller; import com.yourproject.repository.YourMongoRepo; public class DemoController extends Controller { private final YourMongoRepo mongoRepo; // 直接用Guice注入Spring管理的Bean @Inject public DemoController(YourMongoRepo mongoRepo) { this.mongoRepo = mongoRepo; } }
第三步:别忘了配置MongoDB连接
最后要确保MongoDB的连接配置正确,可以在SpringConfig.java里添加MongoTemplate的Bean:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.core.MongoTemplate; import com.mongodb.client.MongoClients; @Configuration @ComponentScan(basePackages = "com.yourproject") @EnableMongoRepositories(basePackages = "com.yourproject.repository") public class SpringConfig { @Bean public MongoTemplate mongoTemplate() { // 替换成你的MongoDB连接地址和数据库名 return new MongoTemplate(MongoClients.create("mongodb://localhost:27017"), "your-database-name"); } }
内容的提问来源于stack exchange,提问作者Raya
相关产品推荐
相关产品推荐

