Pat*_*tan 7 java dependency-injection cdi
我有这样的情况.我看不到任何错误,但我没有得到我的结果.
@ApplicationScoped
public class A {
private B b;
@Inject
public A(B b) {
this.b = b;
}
}
@Singleton
public class B {
private A a;
@Inject
public B(A a) {
this.a = a;
}
}
Run Code Online (Sandbox Code Playgroud)
这种类型的依赖注入是错误的吗?
谁能帮我这个.
我会避免这种循环依赖,这样做有几个原因。
评论这篇文章
凌乱的构造函数是一个标志。它警告我,我的班级正在成为一个庞然大物,它是各行各业的杰作,却一无所获。换句话说,一个凌乱的构造函数实际上是一件好事。如果我觉得一个类的构造函数太乱了,我知道是时候做点什么了。
而这个
您会发现类 A 需要 B 的实例而 B 需要 A 的实例的情况。这是循环依赖的典型情况,显然很糟糕。根据我的经验,解决方案是让 B 成为 A 的一部分,当两者非常依赖以至于它们真的应该是一个类时。更常见的是,至少还有一个 C 类隐藏在那里,因此 B 不需要 A 而只需要 C。
尤其是构造函数注入实际上可以防止您引入循环依赖。如果你确实引入了它们,你本质上就是把两方合二为一,因为你不能真正改变一方而不冒破坏另一方的风险,这在任何情况下都是一种设计味道。
这是我可能会做的一个小例子。
public class A {
private B b;
@Autowired
public A(B b) {
this.b = b;
}
public void doSomeWork() {
// WORK
}
public void doSomeWorkWithB() {
b.doSomeWork();
}
}
public class B {
private A a;
@Autowired
public B(A a) {
this.a = a;
}
public void doSomeWork() {
// WORK
}
public void doSomeWorkWithA() {
a.doSomeWork();
}
}
Run Code Online (Sandbox Code Playgroud)
重构后它可能看起来像这样。
public class A {
private C c;
@Autowired
public A(C c) {
this.c = c;
}
public void doSomeWork() {
// WORK
}
public void doSomeWorkWithC() {
c.doSomeWorkThatWasOnA();
}
}
public class B {
private C c;
@Autowired
public B(C c) {
this.c = c;
}
public void doSomeWork() {
// WORK
}
public void doSomeWorkWithC() {
c.doSomeWorkThatWasOnB();
}
}
public class C {
public void doSomeWorkThatWasOnB() {
// WORK
}
public void doSomeWorkThatWasOnA() {
// WORK
}
}
Run Code Online (Sandbox Code Playgroud)
引用CDI 规范 1.2 的第 5 节:
容器需要支持 bean 依赖图中的循环,其中至少有一个 bean 参与每个循环依赖关系链具有正常范围,如正常范围和伪范围中所定义。容器不需要支持循环依赖链,其中每个参与链的 bean 都有一个伪作用域。
ApplicationScoped 是一个正常的范围,所以这个循环应该可以工作。
在您的示例中,类A不能被代理,因为它缺少零参数构造函数。添加此构造函数(可能具有受保护或包可见性),您的示例部署没有问题。
| 归档时间: |
|
| 查看次数: |
3426 次 |
| 最近记录: |