SpringBoot自动配置的简单分析

SpringBoot的"习惯优于配置"理念,使我们快速搭建开发环境.但是我们底层中到底是怎么实现的呢。这是SpringBoot学习之路(二)中Demo的HelloApplication.java里的一个片段.

SpringBoot自动配置的简单分析_第1张图片

SpringBoot的快速启动是靠SpringApplication类来引导启动,执行的是SpringApplication.run方法。。。所以我们有理由相信我们的自动配置可能是由SpringApplication类里面,我们往SpringApplication里跟进,找到initalize方法,如下图

SpringBoot自动配置的简单分析_第2张图片

找到了关键的getSpringFactoriesInstances()往下跟进,如下图

SpringBoot自动配置的简单分析_第3张图片

我们根据getSpringFactoriesInstances()的方法体找到了loadFactoryNames()的可疑方法,继续跟进

SpringBoot自动配置的简单分析_第4张图片

获取系统文件的方法:getSystemResources(FACTORIES_RESOURCE_LOCATION),常量值:


我们在spring-boot-autoconfigure.jar配置包里发现META-INF/spring.factories文件.点击打开

SpringBoot自动配置的简单分析_第5张图片

这里只贴出部分代码.我们探究下redis的自动配置,找到这个org.springframework.boot.autoconfigure.data.redis里的RedisAutoConfiguration类

SpringBoot自动配置的简单分析_第6张图片

跟进RedisProperties这个Redis的配置类,

SpringBoot自动配置的简单分析_第7张图片

我们可以看到,关于Redis的各项配置都在这里,注解表示前缀为Spring.redis


接下来简单分析SpringBoot自动配置创建Bean方式我们先了解一下SpringBoot的条件注解,下面列出了一些条件注解

@ConditionalOnBean 当容器中有指定Bean的情况下
@ConditionalOnClass 当类路径下有指定Class的情况下
@ConditionalOnExpression 基于SpEL表达式作为判断条件
@ConditionalOnJava 基于JVM版本作为判断条件
@ConditionalOnJndi 在JNDI存在的条件下查找指定位置
@ConditionalOnMissingBean 当容器中没有指定Bean的情况下
@ConditionalOnMissingClass 当类路径下没有指定Class的情况下
@ConditionalOnNotWebApplication 当前项目不是Web项目的条件下
@ConditionalOnProperty 指定属性是否有指定值
@ConditionalOnResource 类路径是否有指定值
@ConditionalOnSingleCandidate 当指定Bean在容器中只有一个,或者虽然有多个但是指定首选的Bean
@ConditionalOnWebApplication 当前项目是Web项目的条件下
我们打开Web的自动配置看看org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration

拿个最简单的视图解析器来说

SpringBoot自动配置的简单分析_第8张图片

从注解上看@Bean说明这个方法是一个Bean,将要注入进Spring容器,@ConditionalOnMissingBean说明如果我们没有自定义这个Bean,那么SpringBoot将会自动创建,那么我们看下如何自定义Bean。

第一种方式:在HelloApplication.java类里直接写一个Bean,(注意:在Spring4.x之前Bean是在xml文件里,Spring4.x以后,官方推荐使用Java配置,有关这点详见Spring的Java配置方式(无xml),所以我们的Bean方法必须在带有@Configuration类里)

SpringBoot自动配置的简单分析_第9张图片

如上所示,运行SpringBoot,浏览器输入http://127.0.0.1:8080/hello


我们把自定义的Bean注释掉,运行SpringBoot,浏览器输入http://127.0.0.1:8080/hello,结果是这样

SpringBoot自动配置的简单分析_第10张图片


很明显,我们自定义的消息转化器生效了。

第二种方式:我们新建一个类去继承WebMvcConfigurerAdapter,然后重写configureMessageConverters()方法

SpringBoot自动配置的简单分析_第11张图片OK,重新启动SpringBoot,浏览器输入http://127.0.0.1:8080/hello


我们的第二种方式实现了消息转换。。为什么在这里新建类重写就OK呢,

原因是,我们新建的类加了@Configuration,申明这是一个配置xml.然后我们的@SpringBootApplication注解


SpringBoot自动配置的简单分析_第12张图片

我们的@SpringBootApplication注解源码里体现,它会自动扫描同类路径下的所有包(包括子包)里的类。





你可能感兴趣的:(Java框架)