【发布时间】:2018-09-24 04:19:54
【问题描述】:
我正在尝试创建类似 @Enable... 自动配置的东西。我想为自定义库创建这样的注释,该库具有广泛的 spring 配置,但需要提供 2 个 bean,并基于这些 bean 初始化各种上下文。它确实初始化了数组中返回的所有 @configuration 类中的 bean,但我还想根据已注册的 bean 执行一些自定义配置逻辑。现在的javadoc https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/ImportSelector.html
声明
ImportSelector 通常以与常规 @Import 注释相同的方式处理,但是,也可以延迟选择导入,直到处理完所有 @Configuration 类(有关详细信息,请参阅 DeferredImportSelector)。
所以我转向 DeferredImportSelector,因为据说 Selector 在所有 @Configuration bean 之后运行,所以我可以做条件 Bean。现在javadoc在这里很清楚(https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/DeferredImportSelector.html)
ImportSelector 的一种变体,在处理完所有 @Configuration bean 后运行。当所选导入为@conditional
时,这种类型的选择器可能特别有用
所以这对我来说是完美的。好吧,直到事实证明无论我做什么,导入选择器 selectImports 方法总是在所有 @Configuration bean 之前运行。
我发现主 @Configuration bean 可能总是最后一个,而 javadoc 实际上提到了所有导入的 @Configuration bean。看来情况也并非如此。我一直在使用调试器检查优先级,但这是我所做的测试代码,非常简单:
除了 system out 什么都不做的导入选择器:
public class TestImportSelector implements DeferredImportSelector{
@Override
public String[] selectImports(AnnotationMetadata arg0) {
System.out.println("ImportSelector");
return new String[0];
}
}
配置类(导入以检查任何提到的想法是否有效)
@Configuration
public class ImportedTestContext {
@Bean
public String testBeanString2(){
System.out.println("bean2");
return "string2";
}
}
主上下文类(也尝试交换导入的类)
@Configuration
@Import({TestImportSelector.class, ImportedTestContext.class})
public class TestMainContext {
@Bean
public String testBeanString(){
System.out.println("bean1");
return "string";
}
}
最后是我的主要课程
public class Test {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(TestMainContext.class);
}
}
Sooo,当你运行主程序时。你总是得到相同的输出
ImportSelector
bean2
bean1
无论如何,导入选择器总是第一个。此外,我试图按照 javadoc 所说的那样处理 Ordered 接口
实现还可以扩展 Ordered 接口或使用 Order 注解来指示相对于其他 DeferredImportSelectors 的优先级
但似乎甚至没有调用 getOrder 方法。嗯,这可能是因为它说它只检查其他 DeferredImportSelectors(没有但值得尝试)
我已经使用 spring-context 4.3.2.RELEASE 完成了这项工作,因为这是我的项目中使用的,但只是为了确保也使用 5.0.5.RELEASE 进行了测试。 结果完全一样。
所以我相信我对 ImportSelector、DeferredImportSelector、spring 不了解,或者 javadoc 没有说实话或者我误解了它的可能性很小......
如果有任何帮助或建议,我将不胜感激......
明确一点:基于 DeferredImportSelector,我希望它实现 BeanFactoryAware(这部分有效,Spring 确实注入了 BeanFactory),它将检查已经定义了哪些 bean(比如那些有趣的测试字符串 bean)并基于这将告诉 spring 应该加载哪些额外的配置。基于 javadoc,这就是它的用途.....
【问题讨论】:
标签: java spring ioc-container spring-bean