springboot之ImportSelector解析
DeferredImportSelector
介绍
1 | /** |
- 他是ImportSelector的一个扩展实现。基本是在所有的Configuration中所有bean实例化完成后,才会触发。在Import的类是Conditional的时候,这个类型的Selector特别有用。
- 主要实现方法是selectImports,返回对应的全类名。
使用
定义三个Configuration。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
324j
public class MyConfiguration1 {
public MyConfiguration1() {
log.info("MyConfiguration1 construct...");
}
public void execute() {
log.info("MyConfiguration1 execute...");
}
}
4j
public class MyConfiguration2 {
public MyConfiguration2() {
log.info("MyConfiguration2 construct...");
}
public void execute() {
log.info("MyConfiguration2 execute...");
}
}
4j
public class MyConfiguration3 {
public MyConfiguration3() {
log.info("MyConfiguration3 construct...");
}
public void execute() {
log.info("MyConfiguration3 execute...");
}
}定一个导入类
1
2
3
4
5
6public class MyImportSelector implements DeferredImportSelector {
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{MyConfiguration1.class.getName(), MyConfiguration2.class.getName(),
MyConfiguration3.class.getName()};
}
}定一个Configuration进行Import
1
2
3
4
5
6
7
8
9
104j
(MyImportSelector.class)
public class MyConfiguration {
public Object test() {
log.info("MyConfiguration create a object bean...");
return new Object();
}
}启动类
1
2
3
4
5
6
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}查看启动日志
可以看到,在Configuration类中的bean实例化后,才执行Import。
ImportSelector
介绍
1 | /** |
基本就是返回需要被Import到容器中的class。
使用
1 | public class MyImportSelector implements ImportSelector { |
- 看下启动日志
和Deferred的区别就是他是先Import的。
AnnotationMetadata这个类
这个比较实用。记得之前写过一个分布式任务调度的框架,如果结合springboot,那么在做一些自定义配置的时候就好很多。如:
定义一个注解
1
2
3
4
5
6
7
8
9
10(ElementType.TYPE)
(RetentionPolicy.RUNTIME)
(MyHttpDeferredImportSelector.class)
public MyHttp {
String name() default "";
String value() default "";
}注解实现类
1
2
3
4
5
6
7
8
9
10
114j
public class MyHttpDeferredImportSelector implements DeferredImportSelector {
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
importingClassMetadata.getAllAnnotationAttributes(MyHttp.class.getName(),true)
.forEach((k,v) -> {
log.info(importingClassMetadata.getClassName());
log.info("k:{},v:{}",k,String.valueOf(v));
});
return new String[0];
}
}使用注解
1
2
3
4
5
6
7
8
9
10
114j
"myc1",value = "myc1-value") (name =
public class MyConfiguration1 {
public MyConfiguration1() {
log.info("MyConfiguration1 construct...");
}
public void execute() {
log.info("MyConfiguration1 execute...");
}
}
我们运行的时候能看到如下结果:
我们能取到使用注解类的所有信息。这样子,在自定义一些处理规则的时候,会方便很多。
总结
ImportSelector这个springboot的钩子,一般配合Import注解使用,功能还是比较强大的。在自定义一些注解的时候,比较好用。
本文作者 : braveheart
原文链接 : https://zhangjun075.github.io/passages/springboot-ImportSelector/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
知识 & 情怀 | 二者兼得