Spring Boot 2从入门到入坟 | 自动配置篇:源码分析之初始加载自动配置类
发布日期:2021-06-30 17:57:23 浏览次数:3 分类:技术文章

本文共 19792 字,大约阅读时间需要 65 分钟。

在上一篇文章中,我们已分析完了@EnableAutoConfiguration注解里面的第一个核心注解了,即@AutoConfigurationPackage,它只是指定了默认的包规则,大家还有印象吧!接下来,在这篇文章中,咱们接着来分析@EnableAutoConfiguration注解里面的第二个核心注解,即@Import({AutoConfigurationImportSelector.class})。很明显,该注解是利用ImportSelector接口来给容器中批量导入一些东西的,只要研究清楚了导入了哪些东西,那么@EnableAutoConfiguration注解就算是分析完了。

@Import(AutoConfigurationImportSelector.class)详解

我们不妨点进AutoConfigurationImportSelector类的源码里面去看一看,看一下利用它给容器中批量导入了哪些东西。进入该类的源码里面之后,往下翻,相信你很快会看到一个selectImports方法,如下图所示。

在这里插入图片描述

从该方法中我们就能清楚地看到它到底给容器中要导入了哪些东东,因为该方法返回的数组里面就规定了要导入哪些东东。而且,从该方法中,我们也能看到,所有要导入的东东都是调用getAutoConfigurationEntry方法得到的。得到之后,最终再转成String数组返回出去。因此,我们只要研究清楚getAutoConfigurationEntry方法就行了,因为所有的核心全部都落在该方法里面了。

最后,我们不妨总结一下,@EnableAutoConfiguration注解就是利用AutoConfigurationImportSelector类中的selectImports方法给容器中批量导入一些组件的,至于要导入哪些组件,研究清楚getAutoConfigurationEntry方法便知道了。

getAutoConfigurationEntry方法的分析

我们不妨点进getAutoConfigurationEntry方法里面去看一看,如下图所示。

在这里插入图片描述

然后,在getAutoConfigurationEntry方法里面打一个断点,如下图所示,以Debug模式来启动咱们的Spring Boot应用,来看看该方法是如何来获取所有自动配置的集合的。

在这里插入图片描述

注意,我们最好把以前的断点都去掉,只留这么一个断点就行。

这时,程序会来到标有断点的代码处,我们不妨按下F6快捷键(Step Over)让程序往下运行,直至运行到下面这行代码处。

在这里插入图片描述

这儿是来获取所有候选的配置的。不用废话,继续按下F6快捷键(Step Over)让程序往下运行,在程序往下运行的过程中,大家可以看到会对configurations集合进行一些常见操作,比如从configurations集合里面先移除一些重复的东东,再从它里面排除一些东东等等。在对configurations集合操作了一大堆之后,最终会将其封装并返回,所以,configurations集合就显得特别重要了。

在这里插入图片描述

此时,我们不妨查看一下configurations集合变量的值,如下图所示,发现它里面保存了23个全类名,这23个全类名指定的组件全部都是要导入到容器中的。

在这里插入图片描述

那我这么知道是要导入这23个全类名指定的组件呢?就是通过getCandidateConfigurations方法知道的,因为该方法就是来获取所有需要导入到容器中的配置类的,大家叫组件也行。为了研究得更深入一点,我们不妨在getCandidateConfigurations方法处打上一个断点,如下图所示。

在这里插入图片描述

注意,我们最好把以前的断点都去掉,只留这么一个断点就行。

OK,现在我们再以Debug模式来重新启动咱们的Spring Boot应用,来看一下getCandidateConfigurations方法是怎么来获取到所有需要导入到容器中的配置类的。

这时,程序会来到标有断点的代码处,如下图所示。

在这里插入图片描述

然后,我们不妨按下F5快捷键(Step Into)进入getCandidateConfigurations方法里面去一探究竟。

在这里插入图片描述

可以看到该方法是利用SpringFactoriesLoader(即Spring工厂加载器)来加载一些东东的,那加载的是些什么东东呢?还废什么话啊,直接点进loadFactoryNames方法里面去看一看不就得了。

在这里插入图片描述

似乎loadFactoryNames方法里面又调用了一个loadSpringFactories方法啊!我们再点进去它里面看看,走着。

在这里插入图片描述

可以看到该方法会返回一个Map<String, List<String>>类型的结果,想必大家也猜到了,SpringFactoriesLoader(即Spring工厂加载器)最终就是利用该方法来加载得到所有组件的。

可能有同学会问了,那到底是从哪加载得到所有组件的呢?其实,只要你看懂loadSpringFactories这个方法就知道了。我们不妨再在loadSpringFactories方法处打一个断点,如下图所示,再以Debug模式来重新启动咱们的Spring Boot应用。

在这里插入图片描述

此时,我们来看该方法是从哪加载得到所有组件的。按下F6快捷键(Step Over)让程序往下运行,由于初始定义的result集合为空,所以程序会来到else分支语句里面。当程序来到下面这行代码处时,大伙可以很明显地看到,这儿就是来加载一个资源文件的,而且该资源文件就是META-INF/spring.factories

在这里插入图片描述

所以,loadSpringFactories方法是从META-INF/spring.factories资源文件中来加载得到所有组件的。也就是说,该方法会默认扫描我们当前系统下所有位于META-INF目录下的spring.factories资源文件。

聪明的小伙伴很快就会想到,要不咱们去看看引入的那些jar包里面的META-INF目录下有没有要加载的spring.factories资源文件呗。咱说干就干!

想必你会发现,在咱们引入的这些jar包里面,有些jar包里面的META-INF目录下是没有要加载的spring.factories这个资源文件的,而有些就有,比如与Spring Boot相关的jar包里面就有spring.factories资源文件,如下图所示。

在这里插入图片描述

当然了,除了以上jar包之外,最核心的spring-boot-autoconfigure-2.4.5.jar里面也有META-INF/spring.factories资源文件,而且文件内容如下图所示。

在这里插入图片描述

我们不妨把该文件中最核心的内容贴出来给大家看一下,如下所示。

# Auto Configureorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration,\org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

大家看到没有,Spring Boot应用一启动就要给容器中加载的所有配置类都在spring.factories资源文件中写死了。

也不知道你看到没有,在该资源文件中有一个配置项叫org.springframework.boot.autoconfigure.EnableAutoConfiguration,它后面跟的就是要加载的配置类的全类名,而且加载的每一个配置类都占一行,因为它们后面都有一个换行符(即\)。除此之外,你还会看到,这些要加载的配置类的全类名起得都蛮有规律的,都叫XxxAutoConfiguration,翻译过来就是什么东西的自动配置的意思。也就是说,Spring Boot兼容的全场景的自动配置,在这全部列举出来了。

大家不妨数一数总共有多少个自动配置类,算了,我还是直接告诉大家吧!总共有130个。这130个自动配置类的全类名全写死在spring.factories资源文件中了,这样,只要咱们的Spring Boot应用一启动,那么就会给容器中加载所有的自动配置类。其实,这句话也能这么来说,且听我下面娓娓道来。

那么问题随之就来了,真要把这么多自动配置类全加载进来吗?显然不是,因为有可能容器里面都没有这么多组件,还记得我们之前在主程序类中打印所有组件定义的名字时,容器里面真的有这么多组件的名字可供我们打印吗?难道说一股脑的加载这么多,我们容器里面就真的有这么多了吗?未必吧!下面我不妨给大家看看容器里面到底有多少个组件。

package com.meimeixia.boot;import org.springframework.boot.SpringApplication;import org.springframework.boot.SpringBootConfiguration;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.ComponentScan;/** * 主程序类,也叫主配置类 * @author liayun * @create 2021-04-19 4:02 *///@SpringBootApplication@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan("com.meimeixia.boot")public class MainApplication {
public static void main(String[] args) {
// 1. 返回IoC容器,IoC容器里面就包含了当前应用的所有组件 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); // 这是固定写法哟 // 2. 我们可以来查看下IoC容器里面所有的组件,只要能查找到某一个组件,就说明这个组件是能工作的,至于怎么工作,这就是我们后来要阐述的原理了 String[] names = run.getBeanDefinitionNames(); // 获取所有组件定义的名字 for (String name : names) {
System.out.println(name); } // 3. 从容器中获取组件 int count = run.getBeanDefinitionCount(); // 获取所有bean定义的总数 System.out.println("count = " + count);// String[] beanNamesForType = run.getBeanNamesForType(CacheAspectSupport.class);// System.out.println("======" + beanNamesForType.length);//// String[] beanNamesForType1 = run.getBeanNamesForType(WebMvcProperties.class);// System.out.println("======" + beanNamesForType1.length);// Pet tom01 = run.getBean("tom", Pet.class);// Pet tom02 = run.getBean("tom", Pet.class);// System.out.println("组件是否为单实例:" + (tom01 == tom02));//// // 配置类打印:com.meimeixia.boot.config.MyConfig$$EnhancerBySpringCGLIB$$4559f04d@49096b06// MyConfig bean = run.getBean(MyConfig.class);// System.out.println(bean);//// // 如果@Configuration(proxyBeanMethods = true),代理对象调用方法// User user = bean.user01();// User user1 = bean.user01();// System.out.println("(user == user1) = " + (user == user1));//// User user01 = run.getBean("user01", User.class);// Pet tom = run.getBean("tom", Pet.class);// System.out.println("用户的宠物:" + (user01.getPet() == tom));//// // 4. 获取组件// System.out.println("=====================");// String[] beanNamesForType = run.getBeanNamesForType(User.class); // 获取我们给容器中注册的User类型的组件的名字// for (String s : beanNamesForType) {
// System.out.println(s);// }//// DBHelper bean1 = run.getBean(DBHelper.class);// System.out.println(bean1);// boolean tom_pet = run.containsBean("tom");// System.out.println("容器中tom组件:" + tom_pet);//// boolean user01 = run.containsBean("user01");// System.out.println("容器中user01组件:" + user01);//// boolean tom666 = run.containsBean("tom666");// System.out.println("容器中tom666组件:" + tom666);// boolean haha = run.containsBean("haha");// boolean hehe = run.containsBean("hehe");// System.out.println("haha:" + haha);// System.out.println("hehe:" + hehe); }}

停掉Spring Boot应用的断点调试,改成以普通方式运行,这时,IDEA控制台打印的结果如下图所示。

在这里插入图片描述

可以看到,容器里面组件的总数是141,可以想见,这141个组件肯定不是全部包括了spring-boot-autoconfigure-2.4.5.jar/META-INF/spring.factories资源文件里面所有要加载的自动配置类,因为容器里面必定还包含有一些我们乱七八糟的自定义组件。

所以,可以这样说,虽然这130个场景的自动配置在Spring Boot应用启动的时候会默认全部加载,但是哪些生效,哪些不生效,还得按需开启自动配置项。怎么个按需开启法呢?下面我就带着大家来分析一下。

按需开启自动配置项

大家不妨展开spring-boot-autoconfigure-2.4.5.jar下的org.springframework.boot.autoconfigure包好好看看,只要眼睛不瞎,都会看到Spring Boot所有场景的自动配置。

我们不妨点开aop包下的AopAutoConfiguration自动配置类,看看aop功能能否实现。

在这里插入图片描述

显然是不能的,这是为什么呢?因为该自动配置类里面的AspectJAutoProxyingConfiguration内部类头上标注了@ConditionalOnClass({Advice.class})这么一个注解,它是一个条件装配注解,意思就是说只有我们当前应用的类路径里面存在Advice类,AspectJAutoProxyingConfiguration类(它也是一个配置类)里面写的一大堆配置才生效,如下所示,该配置类里面有JdkDynamicAutoProxyConfiguration、CglibAutoProxyConfiguration等自动代理相关的一堆东东,看起来还是感觉蛮复杂的,是不是啊?咱们也不深究了😜

@Configuration(    proxyBeanMethods = false)@ConditionalOnClass({
Advice.class})static class AspectJAutoProxyingConfiguration {
AspectJAutoProxyingConfiguration() {
} @Configuration( proxyBeanMethods = false ) @EnableAspectJAutoProxy( proxyTargetClass = true ) @ConditionalOnProperty( prefix = "spring.aop", name = {
"proxy-target-class"}, havingValue = "true", matchIfMissing = true ) static class CglibAutoProxyConfiguration {
CglibAutoProxyConfiguration() {
} } @Configuration( proxyBeanMethods = false ) @EnableAspectJAutoProxy( proxyTargetClass = false ) @ConditionalOnProperty( prefix = "spring.aop", name = {
"proxy-target-class"}, havingValue = "false", matchIfMissing = false ) static class JdkDynamicAutoProxyConfiguration {
JdkDynamicAutoProxyConfiguration() {
} }}

但是什么时候才会有Advice这个类呢?不知你看到没有,该类是位于org.aspectj.weaver包下的,如下图所示。

在这里插入图片描述

所以,只有当你导入aop相关的包之后,才会有Advice这个类,继而aop场景下的自动配置才会生效。

举一反三下,你觉得批处理场景下的自动配置能生效吗?你呀不妨点进batch包下的BatchAutoConfiguration自动配置类里面去瞧一瞧,就能知道批处理场景下的自动配置是否能生效了。我觉得应该是不能生效的,你想啊,咱们都没有导入批处理相关的场景,自然也就没有批处理相关的那些包和类了!照理来说,应该会在BatchAutoConfiguration自动配置类里面看到很多类都是发红的,但是不知我这儿怎么就没有这样的现象。

同理,cassandra数据库访问场景下的自动配置能生效吗?显然不能嘛!因为咱们都没把cassandra数据库访问相关的类导入进来,也就是说我们当前应用的类路径里面都不存在这些类,何谈能生效呢?

总结

虽然Spring Boot应用一启动的时候会一股脑的加载所有场景下的自动配置,但是最终还是得根据条件装配规则来按需开启自动配置项。这都得益于Spring Boot底层的条件装配注解(即@ConditionalOnXxx),例如@ConditionalOnMissingBean,也就是说好些场景下的自动配置是不能完全开启的。

以上就是Spring Boot自动配置的核心。

在下一篇文章中,我会为大家介绍几个自动配置实例,再来深入地研究一下自动配置的流程,敬请期待哟😁

转载地址:https://liayun.blog.csdn.net/article/details/116376189 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Spring Boot 2从入门到入坟 | 最佳实践篇:Spring Boot应用该如何编写?
下一篇:Spring Boot 2从入门到入坟 | 自动配置篇:源码分析之自动包规则原理

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月15日 17时17分38秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

路径规划(一) —— 环境描述(Grid Map & Feature Map) & 全局路径规划(最优路径规划(Dijkstra&A*star) & 概率路径规划(PRM&RRT)) 2019-04-30
神经网络调参实战(四)—— 加深网络层次 & 批归一化 batch normalization 2019-04-30
数据挖掘与数据分析(三)—— 探索性数据分析EDA(多因子与复合分析) & 可视化(1)—— 假设检验(μ&卡方检验&方差检验(F检验))&相关系数(皮尔逊&斯皮尔曼) 2019-04-30
RRT算法(快速拓展随机树)的Python实现 2019-04-30
路径规划(二) —— 轨迹优化(样条法) & 局部规划(人工势能场法) & 智能路径规划(生物启发(蚁群&RVO) & 强化学习) 2019-04-30
D*算法 2019-04-30
强化学习(四) —— Actor-Critic演员评论家 & code 2019-04-30
RESTful API 2019-04-30
优化算法(四)——粒子群优化算法(PSO) 2019-04-30
数据挖掘与数据分析(三)—— 探索性数据分析EDA(多因子与复合分析) & 可视化(2)——回归分析(最小二乘法&决定系数&残差不相关)&主成分分析&奇异值分解 2019-04-30
数据在Oracle中的存储 2019-04-30
优化算法(五)—人工蜂群算法Artificial Bee Colony Algorithm(ABC) 2019-04-30
轨迹规划 trajectory planning 2019-04-30
AGV自动导引运输车 2019-04-30
Trie树(字典树) 2019-04-30
COMP7404 Machine Learing——Logistic Regression 2019-04-30
COMP7404 Machine Learing——Regularization(参数C) 2019-04-30
COMP7404 Machine Learing——KNN 2019-04-30
COMP7404 Machine Learing——SVM 2019-04-30
COMP7404 Machine Learing——Decision Tree & Random Forests 2019-04-30