Spring Boot根据我们的开发行为自动猜测并准备使用的bean,只要开发者导入相关的类,Spring Boot就能自动加载可能需要用到的bean,无需开发者手动配置,从而简化了开发流程。
自动配置的意义就是加速开发效率,将开发者使用某种技术时需要使用的bean根据情况提前加载好,实现自动配置的效果。当然,开发者有可能需要提供必要的参数,比如你要用mysql技术,导入了mysql的坐标,springboot就知道了你要做数据库操作,一系列的数据库操作相关的bean都给你提前声明好,但是你要告诉springboot你到底用哪一个数据库,像什么IP地址啊,端口啊,你不告诉spirngboot,springboot就无法帮你把自动配置相关的工作做完。
@SpringBootApplication
public class SpringbootDemo {
public static void main(String[] args) {
SpringApplication.run(SpringbootDemo .class, args);
}
}
在Spring Boot项目中的引导类上有一个注解@SpringBootApplication,这个注解是对三个注解进行了封装,分别是:
其中`@EnableAutoConfiguration`是实现自动化配置的核心注解。?
该注解通过`@Import`注解导入对应的配置选择器。关键的是内部就是读取了该项目和该项目引用的Jar包的的classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。?
在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。
一般条件判断会有像`@ConditionalOnClass`这样的注解,判断是否有对应的class文件,如果有则加载该类,把这个配置类的所有的Bean放入spring容器中使用。
spring.factories文件作用
spring.factories文件是Spring Boot自动配置的核心文件之一,它的作用是将各种自动配置类与对应的配置类集中在一起,方便Spring Boot自动装配。在Spring Boot启动时,它会扫描classpath下所有的spring.factories文件,加载其中的自动配置类,并将它们注入到Spring ApplicationContext中,使得项目能够自动运行。该文件的格式为键值对,键是自动配置类的全限定名,值是该自动配置类所对应的配置类的全限定名。
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.itheima.bean.CartoonCatAndMouse
这个文件就做了一件事,通过这种配置的方式加载了指定的类。转了一圈,就是个普通的bean的加载,和最初使用xml格式加载bean几乎没有区别 ?
自动配置的核心是条件匹配,不同的条件加载不同的Bean,从而启用不同的功能特性。在Spring Boot中,使用了一系列的@ConditionalXXX
注解来定义条件。其中,最常用的包括:
@ConditionalOnClass
和@ConditionalOnMissingClass
,用于检测类的存在与否。简单的说就是,应用程序有没有直接或者间接的引用了包含这个类的jar包。比如,你要开启Undertow服务器的自动配置,就要引入Undertow相关的jar包。@ConditionalOnBean
和@ConditionalOnMissingBean
,用于检测Spring容器中是否已经注册了指定的Bean。通过使用这些条件注解,开发者可以根据需要注册自定义的Bean,以覆盖默认的配置。比如Spring提供了多种DataSource
,不过不包含Druid
,你就可以自定义一个基于Druid
的DataSource
Bean,覆盖Spring默认提供的DataSource
实现。@ConditionalOnProperty
,用于检测当前的Environment中是否配置了指定的属性,这些属性可以来自配置文件,JVM系统属性,操作系统的环境变量等。比如Hikari
的其中一个条件是@ConfigurationProperties(prefix = "spring.datasource.hikari")
。@ConditionalOnResource
,用于检查是否存在特定的资源,比如是否存在某个配置文件,这种条件用到的很少。@ConditionalOnWebApplication
和@ConditionalOnNotWebApplication
,用于检测应用类型是否为Web应用。@ConditionalOnWarDeployment
和@ConditionalOnNotWarDeployment
注解用于判断是否是一个部署在Servlet容器上的传统WAR应用,而使用内嵌的web服务器的应用就不符合此条件。@ConditionalOnExpression
可以用SpEL表达式指定条件规则。要注意, 如果在表达式中引入了其它bean,会导致提早初始化这些bean。此时,这些Bean的状态可能是不完整的,因为它还没有经过Post Processor(比如属性绑定)的处理。建议先用上面的几种条件,无法满足再考虑这种。