SpringBoot自动配置简单分析
从事开发三年了,一直也没有正儿八经的学过和记一些东西。介于提高自身技术。决定开始把看到的东西通过自己能理解的方式写下来,希望对自己或者其他像我一样的初学者有帮助吧。
而且现在大部分公司基本都选择使用SpringBoot整合其他框架进行开发。个人觉得它只是把我们常用的一些依赖和配置都打包好了,可以满足几乎所有的开发工作。当我们启动的时候自动就会去加载依赖。不需要像原来ssm或者ssh中繁琐的xml文件配置了。
由于能力有限、并且其他博主总结的应该比我全面,所以不足的地方还请多多留情哈~不过有一点到是真心觉得:基础很重要!类加载、反射、动态代理、JVM等等,感觉归根结底就是这些东西。
本文使用IDEA创建的SpringBoot项目。如何创建就不过多说了。下面具体分析一下:
启动类:
package com.example.springbootdemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringbootdemoApplication { public static void main(String[] args) { SpringApplication.run(SpringbootdemoApplication.class, args); } }
首先看到的是@SpringBootApplication注解和 SpringApplication.run这个运行程序。可见想要知道启动的原理我们进到@SpringBootApplication看看里面做了什么操作。
@Target({ElementType.TYPE}) //目标 元素类型 所修饰的对象范围 @Retention(RetentionPolicy.RUNTIME) //预留、保留时间 注解会保留到某个阶段 @Documented //文档 @Inherited //遗传 允许子类继承父类的注解 @SpringBootConfiguration //spirngboot配置 @EnableAutoConfiguration //可以允许自动配置 @ComponentScan( //扫描组织 从扫描的路径中找出标识需要装配的类自动装配 excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} )....
脑子不好使。把注解字面意思和作用简单标注上了,详细做什么用大家可以自行百度。这里就不多说了。
[email protected],[email protected],[email protected],[email protected]
元注解:https://www.cnblogs.com/gmq-sh/p/4798194.html 这里讲的比较详细
到这里我们发现 @EnableAutoConfiguration注解 ,而@SpringBootConfiguration我们点进去之后发现实际上也是根据@Configuration来进行配置的。
也就是说除了元注解,只有三个注解起到主要的作用:
@SpringBootConfiguration(也就是@Configuration) @EnableAutoConfiguration @ComponentScan
接下来我们继续看@EnableAutoConfiguration
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage //自动配置包 可以点进去看一下 有一个@Import(Registrar.class) 具体我就不说啦 @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; }
这里主要的看一下 AutoConfigurationImportSelector 。字面意思 自动配置选择导入。也就是将所有符合自动配置条件的bean定义加载到IoC容器。点进去看一下
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered { private static final String[] NO_IMPORTS = new String[0]; private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class); private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude"; private ConfigurableListableBeanFactory beanFactory; private Environment environment; private ClassLoader beanClassLoader; private ResourceLoader resourceLoader; public AutoConfigurationImportSelector() {} public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!this.isEnabled(annotationMetadata)) { return NO_IMPORTS; } else { AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader); AnnotationAttributes attributes = this.getAttributes(annotationMetadata); //可见在这一行中就是去找可以自动配置的bean List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); configurations = this.removeDuplicates(configurations); Set<String> exclusions = this.getExclusions(annotationMetadata, attributes); this.checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = this.filter(configurations, autoConfigurationMetadata); this.fireAutoConfigurationImportEvents(configurations, exclusions); return StringUtils.toStringArray(configurations); } } . . . protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations =SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct."); return configurations; } protected Class<?> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class;}
根据代码我们可以看到 真正去扫描可以自动配置的bean的角色是 SpringFactoriesLoader 点击去我们看一下
public abstract class SpringFactoriesLoader { public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
定义好了一个位置,也就是启动的时候 自动去这个文件下面去寻找。文件位置在这里:
也是说从classpath中搜寻所有的META-INF/spring.factories配置文件,将key为org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,一起加载到IoC容器。(这里借鉴了别人的博客的一段话)
到这里就算是整理完了。太详细的解读我也不会。毕竟水平太差了。因为面试的时候问过。知道个大概方向。但是说的驴唇不对马嘴。希望能对以后有帮助吧~~~