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

Play 2.8中通过依赖注入访问默认数据库失效问题咨询

根本原因

你在静态方法getDatabase()中手动调用new MyDatabase()创建实例,Play框架的依赖注入容器只会处理它自身托管的实例的@Inject注解,手动创建的实例不会触发依赖注入逻辑,因此database字段始终为null。

正确实现方案

方案1:标准依赖注入用法(推荐)

  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();
    }

    // 其他业务方法
}
  1. 所有需要使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:15:05