@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface 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.class)
@Import可以导入向spring中导入组件 ,可以看下链接的文档
接着看下AutoConfigurationImportSelector.selectImports()方法,
selectImports方法调用是在前面的refresh方法的invokeBeanFactoryPostProcessors中,感兴趣的可以看下spring 源码解析一(bean定义)
@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { //如果AutoConfiguration没开,返回 if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } //将spring-autoconfigure-metadata.properties的键值对配置载入到PropertiesAutoConfigurationMetadata对象中并返回 AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); //获取@EnableAutoConfiguration 注解的属性 AnnotationAttributes attributes = getAttributes(annotationMetadata); //从META-INF/spring.factories文件中获取EnableAutoConfiguration所对应的configurations List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); // 去重,List转Set再转List configurations = removeDuplicates(configurations); // 从注解的exclude/excludeName属性中获取排除项 Set<String> exclusions = getExclusions(annotationMetadata, attributes); // 对于不属于AutoConfiguration的exclude报错 checkExcludedClasses(configurations, exclusions); // 从configurations去除exclusions configurations.removeAll(exclusions); // 应用过滤器AutoConfigurationImportFilter, // 此过滤器检查候选配置类上的注解如@ConditionalOnClass,如果要求的类在classpath 中不存在,则这个候选配置类会被排除掉 configurations = filter(configurations, autoConfigurationMetadata); // 现在已经找到所有需要被应用的候选配置类 // 广播事件 AutoConfigurationImportEvent fireAutoConfigurationImportEvents(configurations, exclusions); return StringUtils.toStringArray(configurations); }
这部分代码比较简单,就是读取META-INF/spring.factories文件,然后过滤EnableAutoConfiguration注解上的exclude,然后再根据去重,再根据@ConditionalOnClass匹配过滤
在spring.factories中可以发现redis,mq,jdbc等等自动启动器,但是却没有发现mybatis的
其实也是,mybatis的包都是手动maven导进来的,可以看下mybatis的自动启动器是怎么实现的
有两个包,一个是mybatis-spring-boot-starter,一个是mybatis-spring-boot-autoconfigure,starter里什么都没有,就是添加了mybatis-spring-boot-autoconfigure的pom文件
可以发现autoconfigure下面也有一个spring.factories文件,里面有个MybatisAutoConfiguration,mybatis自己实现了自启动功能
所以我们如果自己需要实现自动启动器,也可以模仿mybatis实现一个,将实现的AutoConfiguration放到spring.factories文件里。
原文:https://www.cnblogs.com/pjfmeng/p/14448611.html