在前往您的回答之前:
- 是的,你是对的,Hibernate 目前使用 Javassist(过去它使用 GCLib,但它已被弃用)在运行时检测类。
- Hibernate 确实会在运行时创建子类,这些子类可以为您的持久实体提供代理。
简短的回答
遗憾的是,我认为您无法将 Hibernate 配置为使用您自己的工厂。有关详细信息,我邀请您阅读长答案部分。
长答案
据我所知,目前,Hibernate 4.x 仅支持 Javassist 作为其字节码操作提供程序。虽然,它曾经允许您在 3.x 版本中在 GClib 和 Javassist 之间切换。回到那些版本,您可以通过配置名为hibernate.bytecode.provider
.
此设置不再显示在Hibernate 4.1 文档中,但您仍然可以在可选配置属性下的 Hibernate 3.2 文档中找到有关它的信息。
作为一名开发人员,我知道有时我们是一些棘手的人,仅仅因为某些东西不在文档中并不意味着它一定不在代码中 :-) 所以,我认为如果设置仍然存在,我们可以尝试利用它是为了做你想做的事(不过,以不受支持的方式)。
出于好奇,因为我的机器中有 Hibernate 4.0.1 代码(但请注意这不是最新的),我做了一些挖掘......而且惊喜,惊喜财产仍然存在!在跟踪使用过的引用(感谢 Eclipse)后,我最终进入了 org.hibernate.cfg.Environment 类(版本 4.2.0.CR2 的代码),在那里我找到了以下代码(我的版本和 4.2 中的代码都是相同的.0CR2):
public static BytecodeProvider buildBytecodeProvider(Properties properties) {
String provider = ConfigurationHelper.getString( BYTECODE_PROVIDER, properties, "javassist" );
LOG.bytecodeProvider( provider );
return buildBytecodeProvider( provider );
}
private static BytecodeProvider buildBytecodeProvider(String providerName) {
if ( "javassist".equals( providerName ) ) {
return new org.hibernate.bytecode.internal.javassist.BytecodeProviderImpl();
}
LOG.unknownBytecodeProvider( providerName );
return new org.hibernate.bytecode.internal.javassist.BytecodeProviderImpl();
}
到目前为止,我可以说它是您的代理工厂的 Javassist 实现,并且不会有标准的方法来更改它。
疯子旁注
我要说的是纯粹的疯狂,它不应该被考虑到生产代码中,但只有在它真正工作/学术/让事情发生的情况下才会考虑。
<锤子黑客>
- 您可以尝试扩展自己的框架来检测类,以便不仅添加满足您需求的字节码,还添加休眠需要的字节码 - 我会说这就像将您的操作与
org.hibernate.bytecode.internal.javassist.BytecodeProviderImpl
操作合并。
- 然后,您可以重命名扩展类以
BytecodeProviderImpl
将其放在同一个包中org.hibernate.bytecode.internal.javassist
,最后将其放在类路径中的某个位置,类加载器会在 jar 中的那个之前找到它(或者可能使用自定义类加载器)
然后你会喜欢听Hibernate、你的框架和可能整个 JVM 惊慌失措的尖叫,不知道该做什么,或者它可以工作......
</锤子黑客>
无论如何,如果您有时间并愿意尝试,请告诉我是否成功。
更新
在评论部分聊了一会儿之后,我有了使用自定义EntityPersister的想法。因为我对此不太确定,所以我用谷歌搜索了一下,看看我是否能找到一些可以告诉我我的想法是否可行的东西。
甚至比找出我的直觉是否正确更好,我在 Stackoverflow 中发现了一个与您的问题非常相似的问题。可悲的是,那里没有公认的答案。
但是该问题的第一个答案给出了与我的想法类似的链接。引用 Pascal Thivent 的话:
自定义 EntityPersister 实现(您可以在 Hibernate 初始化期间使用自定义 Configuration 为特定实体注册)
确实,该示例适用于 Grails 中的 Hibernate,但在纯 Java 中几乎相同:
public void registerCustomEntityPersister(Configuration configuration) {
final Iterator<PersistentClass> classesIterator = configuration.getClassMappings();
while (classesIterator.hasNext()) {
final PersistentClass persistentClass = classesIterator.next();
if (checkIfIsOneTheClassesThatMatters(persistentClass)) {
persistentClass.etEntityPersisterClass(CustomEntityPersister.class);
}
}
尽管这看起来可行,但看起来工作量太大了,因为实现 EntityPersister 看起来并不那么简单……太多的事情。您可以尝试扩展 Hibernate 使用的默认一个(我真的不知道是哪一个)并尝试覆盖 getProxy() 方法以返回您的检测类之一。
抱歉,如果它仍然不是答案,但遗憾的是我不是 Hibernate 专家,我通常开箱即用,实际上由于 javassist 标签,我发现了你的问题,发现它很有趣。
我希望至少我给了你可以帮助你的信息。