遇到下一个情况:
@ConditionalOnBean(ServiceD.class)
@Component
class ServiceAImpl implements ServiceA {
private ServiceB serviceB;
private ServiceC serviceC;
private ServiceD serviceD;
public ServiceA(ServiceB serviceB, ServiceC serviceC, ServiceD serviceD) {
this.serviceB = serviceB;
this.serviceC = serviceC;
this.serviceD = serviceD;
}
}
interface ServiceD {
void doStuff();
}
@Component
class ServiceDImpl implements ServiceD {
private ServiceE serviceE;
public ServiceD(ServiceE serviceE) {
this.serviceE = serviceE;
}
@Override
public void doStuff() {
//...
}
}
仅当存在服务D实现时,我才需要加载服务A。
来自@ConditionalOnBean
文档:">该条件只能与到目前为止由应用程序上下文处理的 Bean 定义匹配,因此,强烈建议仅在自动配置类上使用此条件。
我的问题是: 由于ServiceD是ServiceA的依赖项,这是否保证在评估@ConditionalOnBean
时,ServiceD已经由应用程序上下文处理?
如果没有,有没有其他方法可以在不使用自动配置类的情况下解决这个问题?
这是一个已知问题。不能保证在 ServiceA 之前创建 ServiceD Bean,因为您不能从@ComponentScan
更改 Bean 注册的顺序。这就是为什么文档说仅在自动配置类上使用该条件的原因。因此,您要么必须使 ServiceA 自动配置,以便所有其他定义的 Bean 都在 ServiceA Bean 之前定义,要么使用不同的注释,例如@ConditionalOnClass
。
默认情况下,Spring
管理 bean 的生命周期并安排其初始化顺序。
但是,我们仍然可以根据需要对其进行自定义。我们可以选择 SmartLifeCycle 接口或@DependsOn
注释来管理初始化顺序。
您可以尝试使用此注释来指定 Bean 依赖项@DependsOn
。Spring 保证在尝试初始化当前 bean 之前初始化定义的 bean。请参考文档