springboot中的自动装载
首先,先看看Eureka是怎么被加载到Spring容器中的
这里我们需要认识ImportSeletor接口,我们先来看看怎么用:
- 随便创建一个类,作为bean,准备被加载到spring中的类
@Data
public class User{
private String username;
private Integer age;
}
- 创建一个UserConfiguration类
public class UserConfiguration{
@Bean
public User getUser(){
return new User();
}
}
注意,这里的UserConfiguration上没有任何spring的注解,也就是说正常情况下,User的对象是不会被加载到Spring容器中的
- 创建UserImportSelector实现上面说到的ImportSelector接口
public class UserImportSelector implements ImportSelector{
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata){
//获取配置类的名称
return new String[]{ UserConfiguration.class.getName() };
}
}
- 定义一个注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
//重点
@Import(UserImportSelector.class)
public @interface EnableUserBean{
}
- 准备工作完成了,然后我们只有将这个注解写到springboot的启动类上,它就能加载User对象
@EnableUserBean
public class TestApplication{
public static void main(String[] args){
//获取spring容器
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestApplication.class);
}
}
- 我们来看看流程
@EnableUserBean ⇒ UserImportSelector ⇒ UserConfiguration ⇒ User
这种机制是极其灵活的,可以很方便得将外部框架引入到spring中,至于ImportSelector的接口是在哪里被加载到spring容器中的,我们可以全局搜索,找到ConfigurationClassParser这个类,然后找到
private void processImports(ConfigurationClass configClass, ConfigurationClassParser.SourceClass currentSourceClass, Collection<ConfigurationClassParser.SourceClass> importCandidates, Predicate<String> exclusionFilter, boolean checkForCircularImports) {
...
}
这个方法就是利用递归的形式将所有的配置类都加载完成
@SpringBootApplication
我们回头看看@SpringBootApplication注解,我们进入注解中可以看到上面有一个@EnableAutoConfiguration注解,再进入
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
我们发现,上面有一个@Import注解,是不是和上面我们自定义的注解一样,AutoConfigurationImportSelector这个类就是Springboot自定义的ImportSelector
在AutoConfigurationImportSelector这个配置类中加载了什么呢?
- 你自定义的类
- 扫描所有的jar包,找到META-INF/spring.factories下的类
如果有兴趣读读源码的话,可以从selectImports这个方法开始阅读
Springboot加载Eureka
我们找到如图所示的类
上面说到,Springboot会扫描所有的jar包下的META-INF/spring.factories,所有,图中的EurekaServerAutoConfiguration会被找到,并且加载
在EurekaServerAutoConfiguration会加载很多东西,如:EurekaController(对后台管理页面进行跳转管理)