java类组件顺序_如何在Spring Boot中混合自动配置和组件扫描时控制加载顺序

用户故事是这样的:

我们通过使用Spring Boot自动配置机制的库jar公开了一些API . API在初始化期间需要一些胶合逻辑,因此我们将它们放在某些 @Configuration 块的 @PostConstruct 块下并将它们注册为自动配置 .

用户代码基于 @SpringBootApplication ,而他们更喜欢使用 @ComponentScan 来定义bean而不是自动配置 .

所以问题来了,Spring总是首先尝试加载 @ComponentScan 定义的bean,然后是那些自动配置的bean . 因此,如果任何用户bean依赖于尚未初始化的API,那么肯定会失败 .

在混合自动配置和组件扫描的bean时,似乎无法定义bean顺序 . @Order, @AutoConfigureOrder, @AutoConfigureAfter, @AutoConfigureBefore 注释和Ordered接口仅适用于所有自动配置的bean .

当然,如果用户也为他们的bean使用自动配置,它将正常工作 . 但是从用户的角度来看, @ComponentScan 看起来更自然,更简单,特别是 @SpringBootApplication 暗示了当前java包的 @ComponentScan .

我们当前的解决方法是在很早的阶段就急切加载这些API初始化配置 . 对于Web上下文,它是 ServletContextInitializer.onStartup() ,对于其他通用上下文,它是 LoadTimeWeaverAware's @PostConstruct .

@Configuration

@ConditionalOnWebApplication

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)

public class EagerInitWebContextInitializer implements ServletContextInitializer, PriorityOrdered

{

@Autowired

private ApplicationContext appContext;

@Override

public void onStartup(ServletContext servletContext) throws ServletException {

String[] beanNames = appContext.getBeanNamesForAnnotation(EagerInitializer.class);

if (beanNames != null) {

// pre-load all eager initializers

for (String name : beanNames) {

appContext.getBean(name);

}

}

}

@Override

public int getOrder() {

return Ordered.HIGHEST_PRECEDENCE;

}

}

@Configuration

@ConditionalOnNotWebApplication

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)

public class EagerInitGenericContextInitializer implements LoadTimeWeaverAware, PriorityOrdered

{

@Autowired

private ApplicationContext appContext;

@PostConstruct

protected void init() {

String[] beanNames = appContext.getBeanNamesForAnnotation(EagerInitializer.class);

if (beanNames != null) {

// pre-load all eager initializers

for (String name : beanNames) {

appContext.getBean(name);

}

}

}

@Override

public int getOrder() {

return Ordered.HIGHEST_PRECEDENCE;

}

@Override

public void setLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver) {

// does nothing

}

}

这实际上运作良好 . 但只是想知道有没有更好的方法来实现这一点,或者未来的Spring版本能否提供类似的系统方式?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值