本质就是一个容器,有点类似于Map,用于管理所有的组件(Component)——类似工厂模式中工厂。
还负责管理Compenent之间依赖关系。
请求 ---> 控制器 ----> Service ---> Dao ---> 访问数据库(Datasource、SessionFactory...)
当A组件需要调用B组件方法时,称为A依赖于B。
Spring还会负责将被依赖组件(B)注入给调用组件(A)。
核心功能:
▲ A:管理所有组件(Component): @Component(@Controller、@Service、@Repository)
▲ B:完成依赖注入: @Autowired
▲ Java EE应用涉及到组件:
- 前端控制器组件
- 安全组件(Spring Security,Shiro)
- 业务逻辑组件
- 消息组件(RabbitMQ、Kafka)
- DAO组件(Spring也称其为Repository)
- 连接数据库的基础组件(如DataSource、ConnectionFactory、SessionFactory等)
如果你打算自行管理这些组件及组件的依赖关系,难免形成硬编码耦合。
▲ 有了Spring之后:
- 上面一切组件都交给Spring去管理、放到Spring 容器中。
- 组件之间的依赖关系,也将交给Spring去负责维护。
前端MVC层:Spring WebFlux、Spring MVC、Struts 2(已被淘汰)等。
安全领域:Spring Security、Shiro等。
消息组件:ActiveMQ、RabbitMQ、Kafka等。
缓存:JCache、EhCache、Hazelcast、Redis等。
持久层框架:JPA、MyBatis、jOOQ、R2DBC等。
分布式:ZooKeeper、Dubbo等。
NoSQL存储:Redis、MongoDB、Neo4j、Cassandra、Geodo、CouchBase等。
全文检索引擎:Lucene、Solr、Elastichsearch等。
SQL数据库存储:MySQL、PostgreSQL、Oracle等。
Web服务器:Tomcat、Jetty、Undertow、Reactor Netty等
依然以Spring为核心。
Spring唯一的缺点就是“配置过多”,而Spring Boot为绝大部分第三方框架的快速整合提供了【自动配置】。
针对各种框架提供了对应的Starter,只要添加该Starter即可完成第三方框架的自动整合(添加依赖JAR包)
快速、更方便。
- 内嵌Tomcat、Jetty或Undertow、Reactor Netty服务器,因此Spring Boot应用无需部署到其他服务器。
- Spring Boot应用可做成独立的Java应用程序——不需要是Web应用。
意味着可通过 “java 主类”命令来运行该应用。
- 尽可能地自动配置Spring及第三方框架。
- 完全没有代码生成,也不需要XML配置。
- 提供产品级监控功能(Spring Actuator),如运行状况检查和外部化配置等。
- 不要夸大Spring Boot的功能。
- Spring Boot直译就是“Spring启动”,因此它的主要功能就是为Spring及第三方框架的快速启动提供自动配置。
Spring Boot不属于功能型的框架,当Spring及第三方框架整合起来之后,Spring Boot的任务就完成了。
发挥功能依然是前面列出的那些框架和技术,实际开发必须真正掌握前面列出的那些框架和技术。
- 仅仅学习Spring Boot完全不够。
- 以Spring Boot为核心,沿着Spring Boot所能整合的第三方框架、技术进行学习,将Spring Boot所能整合的第三方框架、
技术都掌握,这样才算真正掌握了Spring Boot——这也就掌握了Java后端开发的技术大成。
因为Maven、各种IDE工具所自带Maven都会尝试创建自己的本地资源库,可能造成你的电脑上出现很多份本地资源库。
- 不方便,
- 耗费空间。
通过设置,无论使用何种IDE工具,都可以共享本地的同一个资源库。
▲ 方式A,利用IDEA的Spring Initializr工具。
File → New → Project → Spring Initializr
JAR: Java常见的压缩包。
WAR:格式和Jar是一样的,只不过它通常是一个Web应用。
添加依赖库 - 可以在创建项目时勾选,实际上也可以在后面直接编辑pom.xml文件。
项目结构下:
|-- src
|-- main:项目开发有关的各种源文件。
|--java: 各种Java源代码。
|--resource: XML、图片、配置文件等各种资源文件。
|-- test:项目开发有关的测试文件。
|--java: 各种测试用例的Java源代码。
|-- pom.xml Maven的生成文件。
|-- mvnw.cmd(mvnw):Maven Wrapper的脚本文件。如果本地有Maven工具,这两个文件其实没太大的作用。
▲ 方式B,利用Spring Boot的官方网站来生成。
https://start.spring.io/ —— 这个网址就是前面IDEA的Spring Initializr的本质。
【备注】方式A和方式B的本质是完全一样的。
方式A必须在IDEA工具中才有效。
方式B则完全没有任何IDE工具的限制。
▲ 方式C,创建一个普通的Maven项目。
直接将已有的Spring Boot项目的pom.xml拷贝过来,稍作修改
——主要改项目信息(groupId、项目名等)、依赖的Starter。
添加如下几个地方,它就会变成一个Spring Boot项目
1. pom.xml要指定一个继承Spring Boot的pom.xml文件。
2. 根据需要添加所用的Spring Boot对应的Starter。
Spring Boot核心(自动配置和大量的Starter组件,用于快速整合各种第三方框架)
3. 添加Spring Boot的Maven插件。
Spring Boot可以整合Spring MVC、Spring WebFlux、Struts 2等各种前端MVC框架。
- 如何开发控制器则取决于用哪种MVC框架。
- 如Spring MVC,则依然使用如下两个注解:
@Controller (是@Component的变体)
@RequestMapping(@GetMapping、@PostMapping、@PutMapping等)
主类用@SpringBootApplication注解修饰。
main方法中只要如下
SpringApplication.run(被@SpringBootApplication注解修饰的类(配置类), args);
▲重点:
@SpringBootApplication相当于如下3个注解的组合
- @SpringBootConfiguration: 就是@Configuration,只不过它的proxyBeanMethods属性默认为true。
@Configuration将被修饰的类变成Java配置类——这就是Spring容器的Java配置方式。
- @EnableAutoConfiguration: 用于开启自动配置。Spring Boot核心注解。
- @ComponentScan:告诉Spring容器要自动扫描哪些类来作为容器中的Bean—— 属于"Spring零配置"部分的知识点。
该注解开启了3个功能:
A. 将被修饰的类变成了配置类。( @Configuration)
B. 开启了零配置的自动扫描。 (@ComponentScan)
默认会自动扫描@SpringBootApplication修饰的类所在包及其子包下的所有组件。
C. 开启了自动配置。(@EnableAutoConfiguration)
▲SpringApplication.run()的两个功能:
- 自动加载该第一个参数所代表的配置类、并创建该配置类中所有Bean,并扫描该配置类相同包中或其子包下的所有Bean。
- 返回所创建的Spring容器
Thymeleaf是下一代的视图模板技术,优点在于:用属性代替原来的子元素
——而浏览器可以自动忽略不能处理的属性,因此浏览器可以直接浏览Thymeleaf视图页面。
▲ 改变:
为
好处:浏览器可以直接查看Thymeleaf的模板页面,当然该模板页面也可被模板引擎解析。
Spring Boot支持Webjar技术,
Webjar:允许将各种前端资源(JS\css等打包成JAR包)
▲ 位置
Thymeleaf的模板页面放在resources/templates目录下
- Spring容器在不在? run()将返回Spring容器。
- Spring配置文件在不在? @SpringBootApplication注解修饰的类就是配置文件。
传统Spring用XML作为配置文件,Spring Boot优先采用Java类(@Configuration修饰的类)作为配置文件。
- @ComponentScan自动扫描注解,依然在!该注解由@SpringBootApplication注解负责提供。
- Spring容器定义、创建、关闭Bean的方式依然没有任何改变。
▲ Spring Boot增强的地方:
它帮我们为整合各种框架提供了自动配置的Bean(比如DispatcherServlet、ViewResolver),
从而简化了Spring的开发以及与第三方框架的整合。
/**********************************
@Configuration:被修饰的类将作为Spring容器的Java配置文件。
@Configuration继承了@Component,因此这意味着@Configuration修饰的类也会变成容器中Bean。
**********************************/
主要是两种方式:
▲ 方式A:在IDE工具中运行Spring Boot主类的main()方法即可。
▲ 方式B,直接用Maven来运行(可以无需IDE工具的支持)
mvn spring-boot:run
◆ 回顾Maven的运行方式:
1. mvn 插件名:goal - 运行指定插件的的指定goal。
2. mvn phase - 让Maven从生命周期的第一个phase开始,一直运行到指定phase。
◆ 可通过如下方式来运行Maven命令:
- 使用操作系统的命令行窗口,进入项目的pom.xml所在的路径,执行 mvn spring-boot:run 即可。
- 使用IDEA的Terminal窗口(其实也就相当于启动了操作系统的命令行窗口)
- 使用Run Anything(双击Ctrl键来启动)
- 通过Maven面板
- 使用运行配置。
【备注:】这5种方式,不仅可用于运行Maven命令,实际可运行其他的任意命令。
Spring Boot应用无需部署到其他Web服务器,Spring Boot应用完全可以独立运行。
发布Spring Boot应用时,只要将该应用打包成一个可执行的JAR包,以后就可直接通过该JAR包来运行Spring Boot应用。
java -jar jar包文件名
▲ 如何打包成JAR包。
(1)保证pom.xml文件中package元素的值为jar,
该元素的默认值就是jar。
(2)使用如下Maven命令:
mvn package - 将项目运行到package阶段。
【备注:】打包时候可能会失败,失败的原因常常有如下两个:
A。你使用了Spring Initializr创建的Spring Boot项目,你的项目中默认是有一个单元测试类,
而package阶段之前要先运行test阶段,
这意味着如果你的单元测试没有通过,那就不会执行打包。
B。资源文件(application.properties等)的字符集是GBK,
而项目希望所有的文件都是UTF-8字符集,此时打包也会失败。
这个可执行的JAR包通常都比较大,因为它集成了大量第三方框架及Web服务器,
以后只要目标机器上有JRE,即可通过java命令来运行Spring Boot项目。
▲ 如何开发Service组件:
只要定义Service类,并使用@Service注解修饰它即可。
▲ 将Service组件注入Controller
方式A(传统):使用@Autowired注解。
方式B(目前主流方式):定义有参数的构造器即可。
Spring Data, JPA, Mybaits,jOOQ……
Spring Boot为常见持久化技术提供了支持。
▲ 例如使用Spring Data JPA来访问数据库,为此首先要为项目添加如下依赖:
- Spring Boot Data JPA依赖,它会自动添加数据源的实现。
- MySQL数据库驱动依赖
只要你添加Spring Boot Data JPA的starter组件,Spring Boot就会为你搞定整合spring data jpa的一切基础配置。
▲ 基于Spring Data开发DAO组件
让DAO接口继承CrudRepository接口
Spring Data会为继承了CrudRepository接口的DAO接口自动为它动态生成实现类,并将该实现类的实例部署在Spring容器中。
此外,Spring Data还可动态为BookDao增加很多查询方法。后面会有详细介绍
预告:Spring Data不仅可以自动生成大量的CRUD方法,也能允许用户定义自定义的查询(sql、HQL),
甚至允许用户使用最底层API(EntityManager、DataSource、Connection……)
▲ 事务控制
如果不用Spring Boot,就需要在Spring配置文件中配置事务管理器、各种事务代理之类的配置。
用了Spring Boot之后,只要在Service中添加@Transational注解,剩下的事情都由Spring Boot搞定。
实际项目开发中,单元测试与业务代码通常都会要求同步进行。
TDD:先编写单元测试,然后努力去开发业务代码去满足所有的单元测试用例。
添加如下依赖:
org.springframework.boot
spring-boot-starter-test
spring-boot-starter-test.jar , 传递依赖了最新JUnit 5.x的单元测试框架。
★ 测试RESful接口
- 测试用例类使用@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)修饰。
- 测试用例类会接收容器依赖注入TestRestTemplate
- 测试方法可通过TestRestTemplate来调用RESTful接口的方法
★ 模拟Web环境测试控制器
模拟Web环境:不需要真正启动Web服务器,只是对Web环境进行简单的模拟。
@SpringBootTest(webEnvironment=WebEnvironment.MOCK)和@AutoConfigureMockMvc修饰测试用例类
测试用例类定义接受依赖注入的MockMvc类型的实例变量,通过该实例变量可用于模拟浏览器来发送请求、
获取返回值:ModelAndView
@Autowired
private MockMvc mvc;
// MockMvc的作用类似于测试RESTful API的TestRestTemplate
// 可用于模拟浏览器发送等各种请求
测试方法编写步骤:
(1)用MockMvc向指定URL发送模拟请求,获取控制器返回的ModelAndView。
(2)用Assertions的断言方法断言ModelAndView中的数据与期望数据一致。
测试Service组件无需启动Web服务器。
故使用@SpringBootTest(webEnvironment = WebEnvironment.NONE)修饰测试用例类即可
测试用例类定义接受依赖注入的Service类型的实例变量,然后通过该变量测试Service组件的方法
Service组件其实就是一个普通的组件,它不需要借助于Web服务器,也不需要启动模拟Web环境。
【Spring Boot提供支持就是】:将被测试的组件注入到测试用例中。
——在Spring Boot应用中,测试所有的普通组件都可以使用该方式。
假设要测试的A组件依赖于B组件,但B组件可能根本就没有开发完成,
或B组件开发出来了,但没有经过严格的测试
如果直接对A组件进行测试,此时可能测试出现的错误并不是A组件导致的,而是A组件所依赖的B组件所导致的。
为了避免B组件将错误传给A组件,或者在没有B组件的前提下,能对A组件进行测试,
此时就需要提供一个B组件的模拟对象——借助于Mockit即可。
(1)定义一个@MockBean修饰的模拟组件
——该模拟组件就代表了被依赖组件(该组件可能未开发完成,或未经过严格测试)
(2)在测试方法中,调用BDDMockito的given()类方法为模拟组件的指定方法直接设置返回值。
——这样即可基于对模拟组件所设置的返回值来进行测试。