前言
用过springmvc的同学都知道,如果我想要在项目中使用mybatis的时候,按照maven项目来说得先引入依赖,再去xml配置bean,还需要在application.properties配置username,password等连接信息,第一次配置好后再写个demo结果一运行控制台都是error就尴尬了。这一折腾大半天过去了,而springboot可以自动配置xml和properties,当然我们也可以修改它提供的默认配置,下面就分析一下它是如何做到的。
引入依赖
这里以mybatis为例,引入springboot的mybatis依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
引入后可以看到下面这四个包,后面两个就是之前在springmvc使用mybatis需要引入的两个依赖。starter包里的pom.xml会把所有用到的依赖都给包含进来, stater机制帮我们完成了项目起步所需要的的相关jar包。那问题来了,传统的spring应用中不是要在application.xml中配置很多bean的吗,比如sqlSessionFactory配置,springboot是如何帮我们完成这些bean的配置的?下面我们来分析这个过程
自动配置
上面的图中在autoconfigure包中有个MybatisAutoConfiguration类我们打开看一下
熟悉@Configuration、@Bean这两个注解的同学或许已经知道了。这两个注解一起使用就可以创建一个基于java代码的配置类,可以用来替代相应的xml配置文件。所以原本需要我们自己手写去配置的xml,现在springboot帮我们做了。
从类上面的注解可以看出,要完成自动配置是有依赖条件的。
这些是springboot特有的,常见的条件依赖注解有:
@ConditionalOnBean,仅在当前上下文中存在某个bean时,才会实例化这个Bean。
@ConditionalOnClass,某个class位于类路径上,才会实例化这个Bean。
@ConditionalOnExpression,当表达式为true的时候,才会实例化这个Bean。
所以要完成Mybatis的自动配置,需要在类路径中存在SqlSessionFactory.class、SqlSessionFactoryBean.class这两个类,需要存在DataSource这个bean且这个bean完成自动注册。
进入DataSourceAutoConfiguration这个类,可以看到这个类属于这个包:org.springframework.boot.autoconfigure.jdbc
这个包又属于spring-boot-autoconfigure这个包,自动配置这个包帮们引入了jdbc、liqiubase、logging、mail、mongo等包。很多包需要我们引入相应jar后自动配置才生效。
bean参数获取
到此我们已经知道了bean的自动配置是怎么回事,但是还没有看到springboot是如何读取yml或者properites配置文件的的属性来创建数据源的。
在DataSourceAutoConfiguration类里面,我们注意到使用了@EnableConfigurationProperties这个注解。点进去DataSourceProperties类,发现类中封装了数据源的各个属性,且使用了注解ConfigurationProperties指定了配置文件的前缀。我们在properties中添加对应的配置就会覆盖默认的。
@ConfigurationProperties: 把yml或者properties配置文件转化为bean。
@EnableConfigurationProperties: 使@ConfigurationProperties注解生效。如果只配置@ConfigurationProperties注解,在spring容器中是获取不到yml或者properties配置文件转化的bean的
bean加载
自此springboot的自动配置已经完成。接下来就看springboot是怎么加载这些bean的。
在启动类上有个@SpringBootApplication的复合注解,其中以下三个重点了解以下。
@EnableAutoConfiguration: 启动自动配置,意思是Spring Boot会根据你添加的jar包来配置你项目的默认设置。
@SpringBootConfiguration:继承自@Configuration,二者的功能也一致,用于标注当前类是配置类。
@ComponentScan:作用是扫描当前包及其子包下被@Component注解标记的类并纳入到Spring容器中进行管理。是spring传统XML配置的< context:component-scan>的替代。
在org.springframework.boot.autoconfigure包中有一个spring.factories文件,里面已经有很多官方默认配置好的xxxAutoConfiguration了,当然并不是全部加载,会依据@ConditionalOnxxx条件注解加载。
总结
springboot的自动配置就是把我们之前需要配置的xml转化成了java代码集成在框架中了,在项目启动时通过引入的jar包判断需要加载哪些bean。