我正在处理一种设计情况,但我不确定如何解决它,或者我的微设计是否有任何问题。
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)的方法。
限制如下:
- 具有要使用的自定义注释和界面的第三方框架 待实现
- 代码必须是可测试的,因此不允许在字段上使用 @Inject/@Autowired
- 我们被限制使用 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/