强制Spring在运行时使用特定的类代替另一个类

时间:2017-01-09 09:10:50

标签: java spring spring-aop

My Spring应用程序依赖于我需要覆盖类的库,比如说com.dep.A。我想创建扩展B的类A,并告诉spring每次A尝试加载(通过任何代码或依赖项)我想加载B代替。

是否有弹簧设置可实现此目的?如果没有,AspectJ会是一个选项(我认为Spring有一个AspectJ功能)?

编辑:对用例更具体一些 如果我只能将自己插入到类A的特定方法的执行流程中,我会非常高兴。实际上,忘记B扩展A:我真正想要实现的是拦截方法A.originalMethod(MyObject o)的执行,并在我的自定义方法o中使用B.interceptOriginalMethod() 1}}。

3 个答案:

答案 0 :(得分:2)

由于该类来自不同的库,它听起来不像是一个spring bean,然后Spring无法帮助你。它基本上归结为如何构造对象,如果你没有调用 new 运算符,但是库中的代码只有两个选项(除非Jar已经签名,那么我认为有没有选择)。

  1. 加载时间编织。这允许您插入一个切割点并替换该方法的代码。这需要使用java代理启动JVM,并且应该是最后的手段。
  2. 如果您有源代码,则可以使用类阴影。您只需将类源复制到源树(相同的包名称)。这是有效的,因为 / classes 几乎总是在类路径中的库之前,所以当类加载器尝试加载类时,它会找到你的修改版本,从而遮蔽了原始版本。
  3. 我曾经多次使用选项2修复不同开源库中的小问题,当时我懒得从源代码重建整个库。升级库时必须小心,以防它们更改底层代码。

答案 1 :(得分:0)

使用@Autowired@Qualifier按名称而不是类型加载bean。以下是示例

@Autowired
@Qualifier("b")
private A a;

上面的代码将加载B类的引用,前提是B也是一个spring bean。

答案 2 :(得分:0)

虽然@Klaus Groenbaek的回答是正确的(我会将其标记为),但我已经使用其他方法解决了我的问题。

我很幸运,com.dep.A用Spring @ConditionalOnMissingBean注释。

因此,只需创建扩展B的bean A并在主应用程序类中声明:

@Bean 
public A a(){ 
  return new A(); 
}

Spring会加载你的类而不是原来的类。