系列文章目录
springboot是如何实现自动装配的(一)注解分析
springboot是如何实现自动装配的(二)条件装配
springboot是如何实现自动装配的(三)静态资源配置源码
前言
上一篇文章我们分析了springboot自动装配中一些比较重要的注解,也知道了springboot在启动的时候会默认加载127个自动配置类。但是这些配置的组件都要装配到容器么?答案是否定的!那么哪些组件要装配,哪些组件不要装配,根据什么规则进行装配呢?所以今天我们来研究一下springboot的条件装配。一、从何处入手
惯例从源码入手,从源码的哪里入手?就从
spring-boot-autoconfigure-2.3.0.RELEASE.jar
这个包入手!
打开包,我们发现有好多组件,每个子包都是一个组件
我们的分析就从这些子包中的AopAutoConfiguration.class开始
具体分析
AOP的自动配置分析
找一个我们熟悉的AOP包来分析,AOP大家都熟悉。但是springboot启动的时候是否装配了AOP组件呢?来看源码。
进入AOP子包打开AopAutoConfiguration这个类。
先看注释
提取几个关键词就是 为spring AOP提供支持,等同于配置类中启用@EnableAspectJAutoProxy
先看开头的几个注解
第一个注解说明这是个配置类
第二个注解,说的是判断在我们的配置文件中,(即application.properties文件)是否存在前缀为
spring.aop 名字为auto且值为true的配置(即pring.aop.auto=true)的配置。matchIfMissing = true
说的是,就算你没有这个配置,我都当你配置了true;
如果为true下面的配置类就生效,所以这个配置类是生效的。
继续看类里面写了什么
红框部分@ConditionalOnClass条件注解,意思是只有存在Advice.class这个类才构建下面这个内部类但是这个类是哪个包呢,我们看上面的引入
原来是这个包下的类,但是看红色的,木有找到这个包!换言之,@ConditionalOnClass(Advice.class)注解下的内部类是不会生效的
继续往下看
看红框部分,正好说的是如果没有org.aspectj.weaver.Advice这个包下的这个类,那么下面的这个内部类才会构建。
下面的注解就是判断在我们的配置文件中是否配置有 spring.aop.proxy-target-class==true,如果没有配置我也当你配置了true;
相当于默认开启AOP功能。
web.servlet的自动配置分析
这里我们来找一个HttpEncodingAutoConfiguration这个配置类进行分析。
同样先看注释
简单 就是为web应用中使用的编码提供配置
看注解
从上到下,
第一个注解@Configuration(proxyBeanMethods = false):声明这是一个配置类
第二个注解@EnableConfigurationProperties(ServerProperties.class):开启配置生效,将配置文件指定前缀指定名称的配置绑定到ServerProperties.class中。什么前缀什么名称,看ServerProperties类里的定义
第三个注解@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET):要求web应用一定是基于ConditionalOnWebApplication.Type.SERVLET这个类型的应用,看源码这个类型实际上就是基于servlet的WEB应用,由于我们导入的是spring-boot-starter-web这个包那必然是servlet的web应用。
第四个注解@ConditionalOnClass(CharacterEncodingFilter.class):一定要有CharacterEncodingFilter.class这个类,同样只要我们导入了spring-boot-starter-web就会有这个类
第五个注解@ConditionalOnProperty(prefix = “server.servlet.encoding”, value = “enabled”, matchIfMissing = true)判断配置文件是否有server.servlet.encoding=enabled配置,就算没有配置也当是配置了有。就是默认开启encoding。
综上。条件是全部满足的,所以此类可以生效。
继续看类里面都干了些啥
上来先通过构造方法,将配置文件中的编码配置引入到类中来。
然后@ConditionalOnMissingBean表示,如果容器中没有配置则进行配置,如果容器中有了就不进行配置了,容器中要怎么有呢,就是我们自己配置。所以能看出来,这是以用户自定义优先的配置。
配置内容就简单了,就是将配置文件中用户配置的字符编码设置到CharacterEncodingFilter中。
总结
1.springboot先来加载所有自动配置类。
2.每个自动类按照条件进行生效。默认都会绑定配置文件中的值。
3.生效的配置类就会给容器中装配很多的组件,只要容器中有这些组件,相当于这些功能就有了。
4只要用户有自己配置的,就以用户的优先。