Java - 仅在没有字段@Autowired的 super 构造函数中注入(inject)bean

标签 java unit-testing dependency-injection superclass jsr330

我正在处理一种设计情况,但我不确定如何解决它,或者我的微设计是否有任何问题。

public abstract class A implements SomeFrameworkInterface {

  private final Param1 a1;

  @Inject
  private Param2 a2;

  protected A(Param1 a1) {
    this.a1 = a1;
  }

  @Override
  public someFrameworkInterfaceMethod() {
    //code
    doMyStuff();
  }

  protected abstract void doMyStuff();
} 

@Named
@SomeCustomAnnotation(property="someProperty")
public class B extends A {

  @Inject
  public B(Param1 b1) { //b1 is different for every implementation of class A, through some annotations
    super(b1);
  }

  @Override
  protected void doMyStuff() {
    //code
  }

}
  • 我需要将 A 类中的“@Inject Param2 a2”更改为要注入(inject)的 通过构造函数,所以代码是可测试的,我会 清除与此相关的代码气味。
  • 我不想从 B 构造函数发送它,因为我会 在 B 构造函数、A 构造函数中再添加一个参数 对于 A 的所有实现中的每个构造函数...但是 子类永远不需要知道 Param2 实例。
  • Param2 可能是静态的,但需要注入(inject),因为它是 组件(@Named),所以我没有找到静态注入(inject)的方法。

限制如下:

  1. 具有要使用的自定义注释和界面的第三方框架 待实现
  2. 代码必须是可测试的,因此不允许在字段上使用 @Inject/@Autowired
  3. 我们被限制使用 Spring,它被“封装”在 提到了自定义框架,因此我们只能使用纯Java (JSR-330)。 (如果 Spring 有任何解决方案,也很高兴了解它)

最佳答案

不经过 B 的构造函数就不可能将任何参数传递给 A 的构造函数,因为您实际上是在构造 B 的实例。A 的构造函数只是被委托(delegate)来构造 B 实例的“A 部分”。

你能做的最多就是将某种“无类型”参数传递给 B 的构造函数,这样至少 B 不会知道 Param2,但即使在我写下它时,这种治疗方法听起来已经比疾病更糟糕了......

我不认为在构建后注入(inject) Param2 会使代码的可测试性降低。 OTOH,使用静态字段肯定可以。

关于Java - 仅在没有字段@Autowired的 super 构造函数中注入(inject)bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49776374/

相关文章:

java - 使用 Guice 设置属性的正确方法是什么?

java - 使用 JNA 和 Windows sendMessage API 从基于 java 的 Web 应用程序更改 Windows XP 中的焦点窗口

java - 抛出异常 - 并且代码进一步执行

java - Wicket编程模型: nesting components

java - 如何在 Java EE 6 中通过 EL 检索上下文参数?

java - 模拟静态方法

django-mptt : . move_to 在测试运行器中不起作用

jquery - 反向 Zen 编码

php - Symfony 依赖注入(inject)组件独立注入(inject) Doctrine 实体管理器

asp.net-mvc-3 - 如何在 MVC3 中的 Unity 中设置 Ambient Context DI?