SpringBoot的"习惯优于配置"理念,使我们快速搭建开发环境.但是我们底层中到底是怎么实现的呢。这是SpringBoot学习之路(二)中Demo的HelloApplication.java里的一个片段.
SpringBoot的快速启动是靠SpringApplication类来引导启动,执行的是SpringApplication.run方法。。。所以我们有理由相信我们的自动配置可能是由SpringApplication类里面,我们往SpringApplication里跟进,找到initalize方法,如下图
找到了关键的getSpringFactoriesInstances()往下跟进,如下图
我们根据getSpringFactoriesInstances()的方法体找到了loadFactoryNames()的可疑方法,继续跟进
获取系统文件的方法:getSystemResources(FACTORIES_RESOURCE_LOCATION),常量值:
我们在spring-boot-autoconfigure.jar配置包里发现META-INF/spring.factories文件.点击打开
这里只贴出部分代码.我们探究下redis的自动配置,找到这个org.springframework.boot.autoconfigure.data.redis里的RedisAutoConfiguration类
跟进RedisProperties这个Redis的配置类,
我们可以看到,关于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
拿个最简单的视图解析器来说
从注解上看@Bean说明这个方法是一个Bean,将要注入进Spring容器,@ConditionalOnMissingBean说明如果我们没有自定义这个Bean,那么SpringBoot将会自动创建,那么我们看下如何自定义Bean。
第一种方式:在HelloApplication.java类里直接写一个Bean,(注意:在Spring4.x之前Bean是在xml文件里,Spring4.x以后,官方推荐使用Java配置,有关这点详见Spring的Java配置方式(无xml),所以我们的Bean方法必须在带有@Configuration类里)
如上所示,运行SpringBoot,浏览器输入http://127.0.0.1:8080/hello
我们把自定义的Bean注释掉,运行SpringBoot,浏览器输入http://127.0.0.1:8080/hello,结果是这样
很明显,我们自定义的消息转化器生效了。
第二种方式:我们新建一个类去继承WebMvcConfigurerAdapter,然后重写configureMessageConverters()方法
OK,重新启动SpringBoot,浏览器输入http://127.0.0.1:8080/hello
我们的第二种方式实现了消息转换。。为什么在这里新建类重写就OK呢,
原因是,我们新建的类加了@Configuration,申明这是一个配置xml.然后我们的@SpringBootApplication注解
我们的@SpringBootApplication注解源码里体现,它会自动扫描同类路径下的所有包(包括子包)里的类。