Springboot-自动配置 AutoConfigure

1.引入案例

1.1 新建一个Springboot项目

新建时,勾选了spring-web组件依赖,创建了一个TestController,配置文件完全是空的,直接跑起来:
项目结构图
浏览器访问http://localhost:8080/test 看看结果
访问结果
看到这里,对springboot不熟悉的小伙伴就会有疑问了(大神请忽略),springboot启动的时候,到底帮我们加载了一些什么配置,别忘了,我们在创建项目的时候在pom文件添加了spring-boot-starter-web组件,点击组件进去可以看到具体的依赖项(太多了,就不贴出来了,有tomcat、webMvc的等等),

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

那么Springboot到底是如何加载我们添加的组件依赖默认组件场景的,这个需要回看我们的主启动类头上有个注解:@SpringBootApplication,点开注解进去看,发现它是个组合注解:

@Target(ElementType.TYPE) //注解的作用域
@Retention(RetentionPolicy.RUNTIME) //注解的生存周期
@Documented //可以被文档化
@Inherited //注解用于标注一个父类的注解是否可以被子类继承
@SpringBootConfiguration //声明为一个配置类 proxyBeanMethods是否开启bean代理,默认是true,从IOC容器中取;如果是false则每次获取都是一个新的实例
@EnableAutoConfiguration //开启自动配置---这个将是我们研究的重点
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) //包扫描的规则

经过分析,开启自动配置的注解是 @EnableAutoConfiguration,点开注解进去看到又是一个组合注解,我们开始分析@Target,@Retention,@Documented,@Inherited这几个上面分析了,不是重点我们忽略掉,关注点放在:@AutoConfigurationPackage和@Import(AutoConfigurationImportSelector.class);

/** @author Phillip Webb
 * @author Stephane Nicoll
 * @since 1.0.0
 * @see ConditionalOnBean
 * @see ConditionalOnMissingBean
 * @see ConditionalOnClass
 * @see AutoConfigureAfter
 * @see SpringBootApplication
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
1.2 分析 @AutoConfigurationPackage

这个类的注释上面写着是“注册packages”,我们看到

/**
 * Registers packages with {@link AutoConfigurationPackages}. When no {@link #basePackages
 * base packages} or {@link #basePackageClasses base package classes} are specified, the
 * package of the annotated class is registered.
 *
 * @author Phillip Webb
 * @since 1.3.0
 * @see AutoConfigurationPackages
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

@Import(AutoConfigurationPackages.Registrar.class),点进去,断点打上,看它做了什么,
在这里插入图片描述
step into 到方法PackageImports上,拿到了启动类BootTestApplication所在的包路径,然后注册到容器中
正是因为有这个注解,我们上面的TestController是在这个com.wxq.csdn包路径下的,默认就能识别到,那其它路径能不能识别呢?

在这里插入图片描述在这里插入图片描述
针对上面的疑问,我们来做一个测试,在主启动类外边再新建一个包,然后写一个TestController01,看看能不能访问到,这里给出结论是访问不到(如下面的两张图),因为Springboot自动配置包路径的时候默认是从启动类所在的包找的,其它路径它是不认识的;那有没有办法让springboot认识这个包路径,办法是有的,不然读源码干嘛,请继续往下看
在这里插入图片描述
在这里插入图片描述
针对上面问题,解决com.wxq.csdn01这个包不识别的问题,
在启动类似@ComponentScan(value = “com.wxq.csdn01”),告诉springboot启动的时候来扫描一下这个包下的类,注册和加载进容器,重启项目,访问刚刚404的地址,结果如下:
在这里插入图片描述

在这里插入图片描述

1.3 分析@Import(AutoConfigurationImportSelector.class)

1.1 先抛出结论:读取所有META-INF/spring.factories配置文件下写死的路径的类加载到容器中,主要是这个spring-boot-autoconfigure包下的spring.factories配置的类;
在这里插入图片描述
1.2 看看springboot是怎么找到spring.factories文件的
通过断点调试发现,主启动类的run方法实现里面调用了refreshContext(context);,这个会调用到AutoConfigurationImportSelector里面的 process方法,下面我们一步一步断点进去看,
先进来主启动类的run方法
在这里插入图片描述
F9继续走下去(因为我提前打好断点了,第一次调试的朋友请用F7 一步一步调进去),方法执行到上面说的process里面,注意一个getAutoConfigurationEntry,
在这里插入图片描述
继续走进去看到这句:List configurations = getCandidateConfigurations(annotationMetadata, attributes); 继续往下走看到这个方法,解析出来的configurations正好是我们上面说的spring.factories配置的Auto Configure
在这里插入图片描述
那么到这里,我们已经知道了springboot如何自动加载配置类,但是加载了不一定就生效的,我们拿下面的例子说明
打开spring-boot-autoconfigure包下的源码,看到的都是springboot默认帮我们准备好的配置场景(图没截取到全部)
在这里插入图片描述
我们拿jdbc这个举例,因为这个大家应该很熟悉,如图,打开DataSourceAutoConfiguration发现有报错,因为我们根本没有引入Jdbc相关的依赖,所以这个配置类是不生效的,@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class }) 这个条件不满足
在这里插入图片描述
我们拿一个生效的配置类举例,因为我们引入了spring-boot-starter-web组件,那么web场景的配置是生效的,我们依旧是看源码,web目录下的配置类,
在这里插入图片描述
点开 DispatcherServletAutoConfiguration这个自动配置类,把DispatcherServlet注册到容器中,这个是springMvc的核心,
在这里插入图片描述

总结

1.自动配置原理,关键在于2个注解**@AutoConfigurationPackage和@Import(AutoConfigurationImportSelector.class)**,上面写的看起来可能不太好懂,但是动手跟着上面的步骤去调试,相信应该能看懂。
2.自动配置类是否生效,需要看我们pom文件里面有没有使用到具体的业务场景,比如上面的案例,我们没有使用到jdbc相关的场景,它的配置类是不生效的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值