本文章很多知识点基于Spring源码解析----@Configuration、@SpringBootApplication、@Bean
@Import标签可以动态的引入一些Configuration类,SpringBoot自动配置也基于这个注解动态引入了很多Conguration类,下面看下使用
1 Demo
将之前文章demo里的MyConfiguration类上的@Configuration注解去掉,加入MyImportDemo类,然后修改启动类,代码如下:
public class MyImportDemo implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
String myConfiguration =
"com.example.springboot.springbootdemo.bean.MyConfiguration";
return new String[]{
myConfiguration};
}
}
@SpringBootApplication
@Import(MyImportDemo.class)
public class SpringBootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemoApplication.class, args);
}
}
启动程序,几时MyConfiguration没有加@Configuration注解,也会被自动引入了,下面看下实现原理
2 实现原理
具体解析代码在ConfigurationClassParser#doProcessConfigurationClass
,上篇文章分析了,这个方法是获取所有ConfigurationClass的地方,其中@Import就是在这里处理的
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
//....
processImports(configClass, sourceClass, getImports(sourceClass), true);
//....
return null;
}
首先调用getImports
方法获取所有使用了@Import
注解引入的类的信息,然后调用processImports
进行处理
private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException {
// 所有引入的类的信息
Set<SourceClass> imports = new LinkedHashSet<>();
// 访问过的类的信息,用来防止重复访问
Set<SourceClass> visited