Spring注解与SpringBoot注解冲突:自定义Spring Boot Starter,服务启动类的@ComponentScan使@AutoConfigureAfter不起作用

键盘手B 发布于 02/28 19:26
阅读 2K+
收藏 1

自定义了一个 SpringBoot starter,该 starter 封装了阿里云MQ生产者和消费者的自动化配置和相关maven依赖。其中依赖了spring-boot-starter-data-redis 做缓存。所以我的自动化配置类的实例化需要在 RedisAutoConfiguration 加载之后进行。使用的spring boot 版本是 1.5.10.RELEASE。

自动配置类部分代码(贴代码居然不让发,说有和谐内容,只能贴图了):

测试过程中没有问题,可以正常使用。然而在实际使用过程中,有几个服务启动时抛异常。

异常信息:

大概意思是OnsAutoConfiguration中的onsRedisCache加载失败,因为依赖的StringRedisTemplate的Bean不存在。

不是指定了 @AutoConfigureAfter(RedisAutoConfiguration.class) 吗?Debug发现,OnsAutoConfiguration 确实比 RedisAutoConfiguration 先加载。为什么@AutoConfigureAfter不起作用??

经过比较发现,这几个服务在SpringBoot启动类都使用了@ComponentScan注解,并且扫包范围包含了我的starter的base package。SpringBoot启动类大概是这样:

@ComponentScan(
        value = {"com.aaa.*.*"}
)
@SpringBootApplication
public class OnsDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(OnsDemoApplication.class, args);
    }
}

尝试把 MQ starter的自动配置类从扫包范围中剔除

@ComponentScan(
        value = {"com.aaa.*.*"},
        excludeFilters = @ComponentScan.Filter(
                type = FilterType.ASSIGNABLE_TYPE,
                classes = {OnsAutoConfiguration.class}
        )
)
@SpringBootApplication
public class OnsDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(OnsDemoApplication.class, args);
    }
}

服务正常启动,MQ功能也可以正常使用。

猜想:莫非 @ComponentScan 使 @AutoConfigureAfter 指定的加载顺序失效了?

这是一个SpringBoot的BUG,还是一个设计好的特点?或者是其他的问题?

欢迎各路高人评论留言顶帖

加载中
0
九

AutoConfigureAfter注解解析只作用于META-INF\spring.factories文件中EnableAutoConfiguration属性对应的class类集合。

键盘手B
我在自定义starter的/META-INF/spring.factories里定义了 org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.aaa.starter.ons.autoconfig.OnsAutoConfiguration
0
九

好神奇,那在org.springframework.boot.autoconfigure.AutoConfigurationImportSelector$AutoConfigurationGroup.selectImports()打下断点,看加载到了没,没有的话,就在附近调一下

键盘手B
回复 @九 : 我的使用方式相当于使用了两次ComponentScan; @ComponentScan("*.*") @SpringBootApplication public class Application {...} 这种场景下,第一个ComponentScan没有做过滤,还是会把其他包下的自动配置类直接加载了
九
回复 @键盘手B : 可以的;spring boot 1.5.0 给 SpringBootApplication 的 ComponentScan 增加了 AutoConfigurationExcludeFilter (spring-projects/spring-boot/issues/7168)
键盘手B
我在这里找到了答案。 https://gooroo.io/GoorooTHINK/Article/17466/Lessons-Learned-Writing-Spring-Boot-Auto-Configurations/29652#.XHjd8ZMzbOS 最后人家给出了建议(Lessons Learned) 谢谢你回复:)
0
键盘手B

@九

这个是加载顺序,可以看到我的自动配置确实在redis之后

返回顶部
顶部