Play 2.8中通过依赖注入访问默认数据库失效问题咨询
根本原因
你在静态方法getDatabase()中手动调用new MyDatabase()创建实例,Play框架的依赖注入容器只会处理它自身托管的实例的@Inject注解,手动创建的实例不会触发依赖注入逻辑,因此database字段始终为null。
正确实现方案
方案1:标准依赖注入用法(推荐)
- 改造
MyDatabase类为DI容器托管的单例,改用构造方法注入依赖,删除手动创建实例的静态方法:
package mytools; import javax.inject.*; import play.db.*; import java.sql.*; @Singleton public class MyDatabase { private final Database database; public Connection dbConnection; @Inject public MyDatabase(Database database) { this.database = database; // 注意:不要长期持有单个Connection实例,避免连接失效/泄漏,建议每次需要操作时临时调用database.getConnection()获取,用完关闭 this.dbConnection = this.database.getConnection(); } // 其他业务方法 }
- 所有需要使用
MyDatabase的位置,都通过构造方法注入的方式获取实例,不要手动new:
举个Controller中使用的示例:
import play.mvc.Controller; import javax.inject.Inject; public class DemoController extends Controller { private final MyDatabase myDatabase; @Inject public DemoController(MyDatabase myDatabase) { this.myDatabase = myDatabase; } // 业务代码中直接使用myDatabase即可 }
方案2:运行时主动获取实例(仅特殊场景使用)
如果确实需要在非DI托管的代码中获取实例,可以通过Play应用的注入器主动拉取托管实例,不要手动new:
public static MyDatabase getDatabase() { // 从Play应用的注入器获取托管的MyDatabase单例 MyDatabase db = Play.application().injector().instanceOf(MyDatabase.class); // 后续逻辑 return db; }
常见注入问题排查思路
- 确认带
@Inject注解的类是否添加了@Singleton等托管注解 - 确认没有手动调用
new创建需要注入依赖的类实例 - 确认注入的依赖类型是Play框架可识别的托管类型,没有自定义未注册的类型
- 自定义包路径下的类确认已被Play的组件扫描覆盖,默认Play会扫描项目根目录下的类,无需额外配置。
内容的提问来源于stack exchange,提问作者Felix Schwarz
相关产品推荐
相关产品推荐

