文章目录
主要是记录自己看源码的思路,所以比较主观。有不正确的地方请指正。共同进步!
首先我是搭建了SSM框架和SpringBoot框架的项目。SSM—SpringBoot
一.SSM和SpringBoot对比
SSM目录:
SpringBoot目录
通过目录可以很清楚的看到同样的功能,SpringBoot比SSM框架要少很多代码。最直观的感受应该是SpringBoot中xml配置文件几乎没有。而SpringBoot是怎么做到的呢?(controller/service/mapper业务逻辑层都一样,不做对比)
1.Dao/Mapper层
SSM:
(1)Sping整合MyBatis主要是在Spring.xml中配置的。其中定义了:
1 datasource,值来源是dbconfig.properties。
2 SqlSessionFactory,SqlSession工厂
3 MapperScannerConfigurer,代理类Mapper接口位置扫包。
三个Bean。
(2)MyBatis中定义了打印日志等配置。
SpringBoot:(下面用SB代替SpringBoot)
(1)代理类Mapper接口位置扫包,这个工作SB在启动类做了:
(2)剩下的除了datasource中关于数据库的相关配置在application.yml中做了,其他的xml中的Bean或配置都是SB帮我们自动做了。后面会进一步说明如何做到的。
2.SpringMVC
SSM:
主要在SpringMVC.xml中进行了相关配置。比如扫包,视图解析器。
SB:
其实都在注解里能找到答案。后面说。
3.项目入口
SSM: web.xml,项目启动首先加载web文件。里面主要配置了Spring和SpringMVC。
SB: 启动类mySpringBoot001Application.java
二.SB启动过程。
Spring Boot 已经将 Java 领域所有主流的技术栈全部进行了集成,自动封装,开发者需要使用的话就不需要手动进行配置,直接“开箱即用”。而做到开箱即用的前提一定是框架帮我们把Bean创建的过程完完成了。SB又是怎么找到要用到的类并创建Bean注入IOC容器的?就要从启动类的 @SpringBootApplication 开始讲起。
1.进入该注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
是元注解,就是用来描述注解的注解,@SpringBootApplication 其实是由 3 个注解组成:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
(1)@SpringBootConfiguration 注解其实就是 @Configuration,@Configuration 是 Spring Boot 中使用频率最高的注解
@Configuration 注解的作用?
实现自动配置,@Configuration 注解的作用是将一个 Java 类标注成为一个配置类。
什么是配置类?
用 Java 类的形式来替代SSM中的 XML 配置文件。
Spring Boot 中没有一个 XML 文件,因为 XML 配置文件的功能全部被配置类替换了,自动配置。
传统的 IoC 配置 XML:
public class Account{
private Integer id;
private String name;
}
<beans>
<bean id="account" class="com.entity.Account">
<property name="id" value="1"/>
<property name="name" value="张三"/>
</bean>
</beans>
@Configuration
@Bean如果不配 value,默认的 id 是方法名 getAccount
@Configuration
public class MyConfiguration {
@Bean(value = "abc")
public Account getAccount(){
return new Account(1,"张三","123123",22, new Date(),new Date());
}
}
等于
<beans>
<bean id="abc" class="com.entity.Account">
<property name="id" value="1"/>
<property name="name" value="张三"/>
...
</bean>
</beans>
这两种方式殊途同归,最后都能从IOC中拿到对应的Bean,但是明显配置类的方式更简单。
小贴士:
一般呢,对象的值都会去配置文件yml中拿。所以上面的配置的方式也可以是“
@ConfigurationProperties 可以直接读取 application.yml 文件中的数据并且封装到 bean 中。
package com.southwind.entity;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "people")
public class People {
private Integer id;
private String name;
private String tel;
}
people:
id: 11
name: 张三
tel: 13678787878
(2)@ComponentScan
替代 XML 中的自动扫包:
该注解的作用是自动扫描并加载符合条件的 bean,通过设置 basePackage 属性的值来指定需要扫描的根目录,该目录下的类及其子目录下的类都会被扫描。可以如下配置:
@ComponetScan(basePackage=“com.southwind”)
如果没有显示设置 basePackage 的值,默认值就是添加了该注解的类所在的包。
启动类一定要放在父包中,所有的业务类一定要被启动类辐射到,否则无法扫描到并注入 IoC。
(3)@EnableAutoConfiguration
是自动配置的核心,非常重要,由两个注解构成:
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
@AutoConfigurationPackage 根据包进行自动装配,底层是 @Import({Registrar.class})
@Import 注解的作用是根据参数中类所返回的信息,将对应的 bean 进行注入
@Import(A.class)
A 类中会返回一部分 bean 信息,@Import 就会将这些 bean 进行注入。
Spring Boot 自动装载的 bean 包括两部分内容:
- 开发者自定义的组件 controller、service、mapper、myconfiguration
- 框架自带组件
在SB项目的启动类里我把加载到程序中的Bean打印出来了,可以看一下。
到这里其实我还有两个疑问:
(1)@AutoConfigurationPackage干的事@ComponentScan不是干了吗?可能是为了防止漏了吧,毕竟@ComponentScan是可以指向性的扫包。
(2)pom中引入的那些maven管理的jar包对应的那些bean是怎么扫入的呢?比如datasource,sqlsession等等。答案都在AutoConfigurationImportSelector.class里面。
2.进入AutoConfigurationImportSelector.class:
其中有这么一段代码:
META-INF/spring.factories。这个在jar包中有啊。以spring-boot-autoconfigure-2.3.2.RELEASE.jar为例:
看到这里已经感觉有点知道它的源头了,是导入这么多的自动配置,才让我们可以开箱即用。从这里面我们可以找到熟悉的datasource和DispatcherServlet等自动配置。
也就是SB项目启动后,会进入Jar包中的spring.factories读取要引入的Bean。
注意: 通过AutoConfigurationImportSelector这个名字也能看出,他是有选择的引入,而不是把所有的都引入。也就是看我们pom引入了什么jar包了。
3.进入spring.factories,查看怎么返回对应的Bean的
SB配置太多了,以MyBatis为例吧:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
进入MybatisAutoConfiguration:
在这里看到了熟悉的东西,datasource类。
@ConditionalOnClass 意思是加载这个类的条件。
@EnableConfigurationProperties({MybatisProperties.class})这个很关键,进入MybatisProperties会看见
这里面就指定了去yml文件中找mybatis开头的配置。比如
对应类中
相应的datasource在:
都找到了对应的值。
总结下来就是要用到的那些Bean通过运行时类和对应的属性值通过动态代理的方式生成了实现类,并注入了IOC容器中。这才做到了SB的开箱即用。
下一篇博客,尝试导入自己的jar包。