【问题标题】:Inject DB Instance For Static and Instance Accessibility为静态和实例可访问性注入数据库实例
【发布时间】:2023-06-24 06:58:02
【问题描述】:

我有一个与 GWT 的 RequestFactory 和关联代理一起使用的 POJO。 POJO 具有需要访问我的数据库的静态方法 (list()) 和实例方法 (persist())。我的数据库连接池设置为通过 Guice 作为单例注入。我不确定的是我该如何执行注入以便这两种类型的方法都可以访问它?

此外,POJO 的实例是使用空构造函数创建的,因此无法使用构造函数注入。

这是一个 POJO 示例供参考:

public class Person {
    private Integer id;
    private String name;

    public Integer getId() { return this.id; }
    public void setId(Integer id) { this.id = id; }
    public String getName() { return this.name; }
    public void setName(String name) { this.name = name; }

    public void persist() {
        //TODO: save state to DB
    }
    public static List<Person> list() {
        //TODO: get all people from DB
        return null;
    }
}

【问题讨论】:

  • 如果你想使用依赖注入,你不应该依赖单例以便注入它吗?即将它传递给对象的构造函数。在这种情况下不能使用空构造函数是我的理解。
  • 我无法控制调用哪个构造函数。我应该更清楚地说明这一点。 RequestFactory 框架自动调用默认构造函数和 setXXX 方法来构建 POJO。如果没有可见的默认构造函数会出错。

标签: java gwt dependency-injection guice requestfactory


【解决方案1】:

不知何故,GWT 的风格仍然不是很清楚依赖注入的需求。这 - 在某种程度上 - 在客户端是可以原谅的,但在服务器端则不然(老实说,我真的希望 GWT 和 Guice 团队能够联手改善这种情况。)

现在,幸运的是,Guice 提供了一种“遗留”机制来注入静态字段,请参阅http://code.google.com/docreader/#p=google-guice&s=google-guice&t=Injections 中的“静态注入”)。因此,您可以将 EntityManager/EntityManagerFactory(或您用于执行持久性的任何内容)注入静态字段。

您不必直接这样做,但您可以使用提供程序。然后选择正确的范围(例如@RequestScoped)以使提供者为您提供正确的实例。

注意:我还没有尝试过(尽管我打算这样做),因为我还没有在实际项目中使用 RequestFactory。我希望遗留机制在这种情况下有效,但您可能会遇到一些障碍(?)

【讨论】:

  • 我不知道为什么我没有想到这一点,但它工作得很好。我的模块创建了一个连接池提供者的热切单例,然后将其静态注入工厂,允许从任何地方进行静态访问。绝对不是最好的解决方案,但它会工作得很好。希望 GWT 的 RequestFactory 在未来的版本中能够意识到可注入的构造函数,这样就可以避免这种情况。此外,我刚刚看到 2.1.1 允许可链接的服务装饰器(显然)允许您执行自定义操作(例如,Guice 实例化)。
【解决方案2】:

如果您使用Locator 来控制RequestFactory 服务器代码如何通过为您的域对象实现Locator.find() 来获取您的POJO 实例,那么pojo 不必是默认可实例化的。定位器还允许您使用不符合 getId() / getVersion() 协议的域对象。

@ProxyFor(value = Person.class, locator = PersonLocator.class)
interface PersonProxy extends EntityProxy { .... }

如果您需要更改大多数域 pojo 的行为,您可以注入一个重载 createDomainObject()loadDomainObject()ServiceLayerDecorator

【讨论】:

  • 如果您需要更多自定义实例化,这绝对是一个好方法。我打算使用这种方法进行 Guice 实例化,但我意识到,由于我已经使用 Guice 绑定为 /gwtRequest URL 提供服务,它也会自动使用 Guice 进行实例化,从而允许 @Inject 构造函数。 github.com/JakeWharton/GwtBase/blob/master/src/main/java/com/…