Java 如何将值可靠地注入到在我的控制之外创建的实例中?

Java 如何将值可靠地注入到在我的控制之外创建的实例中?,java,dependency-injection,Java,Dependency Injection,我有一个类a,它有一个方法foo(),根据某些配置值,其行为会有所不同: class A { private transient Config config; // How do I set this field? public int foo() { return config.hasKey("bar") ? 1 : 2; } } 像Hibernate这样的持久性框架创建A的实例。如何将config的当前值注入实例 注意:我使用的是OJB,不是Hib

我有一个类
a
,它有一个方法
foo()
,根据某些配置值,其行为会有所不同:

class A {
    private transient Config config; // How do I set this field?

    public int foo() {
        return config.hasKey("bar") ? 1 : 2;
    }
}
像Hibernate这样的持久性框架创建
A
的实例。如何将
config
的当前值注入实例

注意:我使用的是OJB,不是Hibernate,但问题本身总是一样的。它可以归结为:我有一些框架为我创建实例。如何将值可靠地注入到在我的控制之外创建的实例中


性能是这里的一个问题,因为创建了数百万个这样的对象。

配置是每个A的状态的一部分?如果这是真的,那么值也必须由您的ORM存储。

虽然答案并不完全是您想要的,但Hibernate为这种类型的处理提供了拦截器。我不熟悉OJB,但你可能会发现类似的东西

你可以让Spring给你的 服务进入休眠状态 使用AOP实例化实例。你 也可以让Hibernate做同样的事情, 使用拦截器

摘自我先前的回答

只是一个想法。。。如果是出于测试目的,最简单的方法是模拟
foo()
以返回所需的值。如果是用于生产,那么我可以考虑使用AOP拦截<代码>脚注()/代码>并将值注入到它。

好的,现在我看到您的配置是暂时的…:)


像这样的东西对你有用吗?

我不知道,这是否有用。来自
Hibernate EntityManager。

long parentId = 12;
EntityManager em ... 
Parent parent = em.getReference(Parent.class, parentId);
parent.setFoo(config);

如果您需要在OJB中执行类似操作,请遵循以下模式:

RowReaderDefaultImpl
调用
ClassHelper.buildNewObjectInstance()
创建从数据库读取的对象。因此,您需要重写
RowReaderDefaultImpl.buildOrRefreshObject()
OJB.properties
中的属性允许您将自己的实现注入系统

不幸的是,没有办法覆盖
ClassHelper.buildNewObjectInstance()
本身(它是
public static

ClassHelper.buildNewObjectInstance()
在另外两个位置调用:

org.apache.ojb.broker.cache.ObjectCacheTowLevelImpl.CopyStrategyImpl.read(PersistenceBroker,Object)
org.apache.ojb.broker.metadata.SuperReferenceDescriptor.SuperReferenceField.getObjectWithDeclaredSuperClass(Object)
不确定它们做什么;我们的项目不需要它们


如果您还需要覆盖这两个,则必须修补OJB的源。

假设由于某些原因,这是不可能的。因此,假设所有A的配置都是全局的。只需创建一个类ConfigProvider或其他东西,将配置注入其中,并在默认构造函数中调用ConfigProvider.getConfig。这会起作用,但也会创建一个全局变量。有没有办法在没有全局变量的情况下做到这一点?每个A的配置都是唯一的?还是所有人都有相同的想法?没有“全局变量”ConfigProvider是一个单例,并通过您选择的DI机制注入配置。单例只是“全局变量”的另一个名称;它破坏了单元测试。:-)如果您使用的是Spring,那么您可以很容易地将ConfigService单例连接到类a中。否则,您可能需要创建一个返回ConfigService的工厂。ObJectRelationalBridge是否提供了任何可用于注入配置的功能?
long parentId = 12;
EntityManager em ... 
Parent parent = em.getReference(Parent.class, parentId);
parent.setFoo(config);