春季@ConditionalOnBean与@Component相结合



遇到下一个情况:


@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 定义匹配,因此,强烈建议仅在自动配置类上使用此条件。

我的问题是: 由于ServiceDServiceA的依赖项,这是否保证在评估@ConditionalOnBean时,ServiceD已经由应用程序上下文处理?

如果没有,有没有其他方法可以在不使用自动配置类的情况下解决这个问题?

这是一个已知问题。不能保证在 ServiceA 之前创建 ServiceD Bean,因为您不能从@ComponentScan更改 Bean 注册的顺序。这就是为什么文档说仅在自动配置类上使用该条件的原因。因此,您要么必须使 ServiceA 自动配置,以便所有其他定义的 Bean 都在 ServiceA Bean 之前定义,要么使用不同的注释,例如@ConditionalOnClass

默认情况下,Spring管理 bean 的生命周期并安排其初始化顺序。

但是,我们仍然可以根据需要对其进行自定义。我们可以选择 SmartLifeCycle 接口或@DependsOn注释来管理初始化顺序。

您可以尝试使用此注释来指定 Bean 依赖项@DependsOn。Spring 保证在尝试初始化当前 bean 之前初始化定义的 bean。请参考文档

最新更新