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

Force Spring to use a specific class in place of another one at runtime

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

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

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

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

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

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

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

  1. 加载时间编织。这允许您插入一个切割点并替换方法的代码。这需要使用 java 代理启动 JVM,这应该是最后的手段。
  2. 如果你有源代码,你可以使用 class 隐藏。您只需将 class 源代码复制到您的源代码树中(相同的包名称)。这是有效的,因为 /classes 几乎总是在 class 路径中的库之前,所以当 classloader 尝试加载 class 它将找到您的修改版本,因此隐藏了原始版本。

我曾多次使用选项 2 来修复不同开源库中的小问题,当时我懒得从源代码重建整个库。升级库时必须小心,以防他们更改了底层代码。

尽管@Klaus Groenbaek 的回答是正确的(我会这样标记),但我已经使用另一种方法解决了我的问题。

我很幸运 com.dep.A 被注释为 Spring 的 @ConditionalOnMissingBean

因此,只需创建 bean Bextending A 并在您的主应用程序中 class 声明:

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

Spring 将加载您的 class 而不是原始的。