繁体   English   中英

Java - 使用实例化反射来防止字段分配?

[英]Java - prevent field assignment using reflection on instantiation?

我在第三方库中有一个java类,其私有成员在类实例化时分配。

public class CacheLookupUtil extends AbstractCacheLookupUtil<InvocationContext> {
  @Inject
  private BeanManagerUtil beanManagerUtil;

  private CacheKeyGenerator defaultCacheKeyGenerator = new DefaultCacheKeyGenerator();
  private CacheResolverFactory defaultCacheResolverFactory = new DefaultCacheResolverFactory();

  ...
  ...
}

我的问题是defaultCacheResolverFactory的赋值由于选择了错误的构造函数而导致异常。

如果我尝试将CacheLookupUtil子类CacheLookupUtil ,那么这个赋值仍然在父类中完成,所以我没有更进一步。

有没有我可以在Java反射中使用的机制允许我构造/实例化对象,但是阻止了defaultCacheResolverFactory的赋值,并允许我通过反射设置值?

我知道这是一个丑陋的解决方案,但说实话,我无法想象任何其他方式继续下去。

DefaultCacheResolverFactory是库jar的一部分吗?

  1. 如果不是,我猜这是一个版本问题。

  2. 否则,您应该留意您的库的修正版本或打开票证。

  3. 最后但并非最不重要的是,您可以使用AspectJ Load-Time Weaving在类加载时操作字节码。 但这要求您始终使用Load-Time Weaving启动代码。 请参阅加载时编织

所以我个人更喜欢选项1或2。

检查包含CacheLookupUtil的库的版本(我理解它是第三方类)。 例如,让它成为jar-A

然后检查包含DefaultCacheResolverFactory的jar版本。 如果它也是jar-A ,这实际上意味着这个库在这个版本上不起作用,所以你应该升级。 如果它在某个jar-B中 ,那么检查jar-A本身的pom.xml ,需要什么版本的jar-B依赖,可能你会覆盖这个jar的版本。

然后调整版本,以便jar-Ajar-B版本的期望匹配:)

对我来说这是最好的解决方案。

现在至于脏伎俩。 一个技巧可以是创建自己的CacheLookupUtil副本并将其放入同一个包中,具体取决于类加载器策略(您没有指定在哪个环境中运行,所以我假设是普通的java)它可能首先加载并有效地加载从jar中“替换” CacheLookupUtil

当然可以使用DefaultCacheResolverFactory完成同样的操作(这样你就可以在那里修复no-op构造函数)

如果您认为它是一个真正的错误,另一个需要考虑的选择是从“buggy”库中分叉并使用修复程序创建自己的版本。 当然,你最好让原始库的开发人员修复这个bug,这样你最终可以回到正式版本,在开源世界,有时这样的解决方案,只要许可允许这样做。

如果它没有帮助,那么Byte Code操作是已经提到的@PowerStat修复的唯一方法。 我相信,Java代理,类加载修补,AspectJ等等。 希望你不会因为这个问题而到达那里:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM