springboot自动配置原理
在使用springboot进行开发的时候,只需要在application.properties中进行参数配置,不配置也会有一个默认值,tomcat,映射关系都不用配置了,那么spring是如何实现自动配置的呢?
springboot如何实现自动装配
自动配置的。这都要归功于springboot强大的注解功能,也是springboot的一大特点
举例:在springboot主运行程序中,下面是常见的springboot启动类
1 |
|
看起来平平无奇,但为什么一运行main方法就会启动容器?
spring会在启动的时候new自己—>new SpringApplication(primarySources).run(args)这时候就会初始化,并加载扫描到所有的组件进入缓存
1 | private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) { |
第一次扫描结果如下,返回18个结果,其中就有后面需要的自动配置包,如红框所示
这么多组件,哪个才会真正的被容器所实例化?
其实真正发挥作用的是@Import(),它导什么,容器实例化什么
先来从@SpringBootApplication这个注解说起
主要的注解为@SpringBootConfiguration+@ComponentScan+@EnableAutoConfiguration
前两个没什么好说的,@SpringBootConfiguration就是封装了@Configuration注解,表示他是一个配置类
@ComponentScan:扫描注解,表示哪些会被spring扫描到
那么重要的就是@EnableAutoConfiguration,见名知意拥有自动配置的能力,点进去看下
主要注解为@AutoConfigurationPackage+@Import,而@AutoConfigurationPackage其中也是@Import,所以起到主要作用的就是@Import这个注解了
@Import:给容器中导入一个组件,前提是必须作用于spring的组件下,可以自动调用组件的无参构造器创建对象
1 |
|
由上图可知import导入了AutoConfigurationImportSelector.class这个组件,那么程序中是什么时候导入的?
spring容器启动会刷新IOC容器(refreshContext(context))执行invokeBeanFactoryPostProcessors方法,最终调用到getImports()这个方法,这个方法会将标有@Import的组件进行实例化
1 | public Iterable<Group.Entry> getImports() { |
上述方法会执行AutoConfigurationImportSelector类的process方法
调用核心方法SpringFactoriesLoader.loadFactoryNames导入一系列组件
拓展部分,怎么导入的?
接上段程序,调用关键语句
1 | List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), |
其中getSpringFactoriesLoaderFactoryClass()返回的正是@EnableAutoConfiguration这个注解
1 | protected Class<?> getSpringFactoriesLoaderFactoryClass() { |
点进去loadFactoryNames
1 | public static List<String> loadFactoryNames(Class<?> factoryType, ClassLoader classLoader){ |
怎么实例化的
spring在刷新IOC的最后一步会调用finishBeanFactoryInitialization(beanFactory)方法,来实例化剩余的非lazy的单例,在调用过程中beanFactory.preInstantiateSingletons(),该方法会遍历所有的bean
然后调用工厂的getBean方法进行实例化
但并不是这133个都会被实例化,还得看条件注解,实现了按需配置
注解有如下几项:
@ConditionalOnBean:当容器里有指定的bean的条件下
@ConditionalOnMissingBean:当容器里不存在指定bean的条件下
@ConditionalOnClass:当类路径下有指定类的条件下
@ConditionalOnMissingClass:当类路径下不存在指定类的条件下
@ConditionalOnProperty:指定的属性是否有指定的值,比如@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true
比如DispatcherServletAutoConfiguration自动配置类中满足DispatcherServlet类存在,并且当前环境是SERVLET的时候才会进行实例化
反观KafkaAutoConfiguration,由于没有导入对应的包KafkaTemplate类也就不存在了,自然这个自动配置类也不会进行实例化
总结
springboot在启动的时候会实例化自动配置包下的组件和我们自定义的组件
我们可以自定义组件也可以按需加载组件,还可以重写spring的组件,因为会优先取用户的配置,没有才会给你默认装配,以上就是关于springboot自动配置的一些原理