Spring Boot 的开发团队叫做Pivotal,Spring Boot 可以简化开发过程,抛弃配置八股文,他的目标就是为了提高开发效率。
spring boot核心特点:
第一个特点就是自动配置以及默认配置,这说的是什么意思呢?以我们一个web项目为例,其实它对外是要暴露端口的,那向这种配置,每一个web项目都要有,那我们SpringBoot就认为,既然每个web项目都要有,我就给你一个默认的配置,这样的话呢,你如果重新配置了的话,就以你的为标准,如果你不去配置的话,就以默认的为效。同样,向Redis和MySQL这些组件会有一系列的众多的一些默认的配置,其实这些默认的配置对与大多数的项目而言他们不一定会去改动。
第二个特点就是起步依赖:starter一站式 。这个起步依赖,在springboot 里面叫做starter,starter一站式服务就可以把你整个所需要用的依赖都引入进来。就比如说,假设我们想引入一个安全框架,那么,你只要引入一个starter,它就会把它所需要的相关的依赖都引进来,相当于对你来说,你不需要关注它需要哪些东西,你只需要关注你想引入它,那么引入一个依赖就够了。所以,这也大大减轻了程序员的开发负担.
第三个特点就是他会创建一个独立的Spring应用程序 。这个说的是什么意思呢,这个是说,我们之前我们需要用Tomcat作为一个容器,把我们的项目打成一个war包,然后把他放到tomcat里面去运行。现在呢,springboot内部就已经嵌入了tomcat,他就不需要额外的去做什么环境配置什么的,你只需要把它当成一个java程序运行,他就能启动起来。所以,在开发的时候,尤其是在部署运行的时候,也给我们带来了很多的便利。
第四个特点就是监控能力强,这个监控能力,如果你需要的话,就可以进行配置,配置好之后,对于内部的很多情况,你都能有所掌控。
最后一个特点就是较少需要XML配置,这种配置其实相对于我们的springboot配置文件而言啊,其实写起来还是比较繁琐的,有很多内容都是样板式的,不需要写。用springboot就可以比较少的去使用xml的配置。当然,少并不代表完全没有,在有些时候我们也是需要它的。
SpringBoot前世今生:
其实springboot诞生的基础和根基就是springframework ,springframework的核心就是IOC和APO。关于这块的内容,前面我的文章都有详细讲过。但是后来我么用这个核心内容去开发一些web项目,组件发现它存在一些繁琐的情况。所以,我们SpringBoot的核心目标就是精简高效,他是建立在我们spring的基础上去开发的,而不是另起炉灶,从零开始的。在后面,我还要学习和微服务相关的东西Spring Cloud,而且Spring Cloud 有一个特点就是集百家之长,他会把很多有用的一些项目和框架集合到一起来形成Spring Cloud。所以对于SpringBoot而言,他的基础是spring的核心,而它进一步的发展就是SpringCloud。
SpringBoot版本介绍:
我们打开SpringBoot的官网来看看,那里会把springboot当前的版本给说明出来,不仅如此,里面还有一些关于springboot的教学和演示。这里只要介绍一下他的版本,这里会有一些符号,比如CURRENT 、GA 、SNAPSHOT 。这些又是什么意思呢?我们究竟如何根据这些标记去选择适合我们的版本呢?当然,springboot的更新版本很快,当你再去打开这个官网的时候,可能他的版本又有了新的迭代,这是很正常的。不过,你们可能会有追新的思想,那是不是最新的就是最好的呢?这里要明确,不是最新最好,因为虽然springboot的版本提高了,但是他需要很多组件去配套的,而这些配套的组件是需要一个适配的过程的,并且组件的新功能我们并不一定会用到。
如果哪个版本是CURRENT版本,它代表是最新的GA版本,那什么是GA呢?GA的意思就是发布版本,他是面向大众的可用的稳定版本。这种版本的特点就是功能完整稳定,一旦发布之后,这个版本就永远不会更改。SNAPSHOT的英文意思是快照的意思,正是因为他叫SNAPSHOT,所以他的内容是会随时被修改的。
有两种springboot项目的方法:
第一种是通过spring官网的方式来创建springboot项目。
下面来学习第二种创建项目的方式:
Idea集成的Spring Initializr。打开Idea之后,新建项目,然后在左侧选择Spring Initializr,其他的就不用多解释了。next后选择版本和依赖,最后finish就行了。
生成好项目后,展开项目的结构。
说到接口,我们快速复习一下web项目的三层结构。通常是分为Controller层,Service层和Dao层。Controller层主要的职责就是对外去提供接口而Service层主要的职责是业务逻辑相关的。而dao层通常是和数据库相关的。我们的项目也不例外,会分为这样的三层。
我们首先在com.haiexijun.springbootlearn下面创建一个包controller。然后去创建一个类。这个类的名称我叫它ParaController。然后要在类上加一个注解@RestController,@RestController的作用就是我们的返回是一个json格式的,而不是一个页面。然后编写如下代码:
package com.haiexijun.springbootlearn.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ParaController {
@GetMapping("/first")
public String firstRequest(){
return "hello springboot,我的第一个接口";
}
}
我们点击运行项目。浏览器访问localhost:8080/first ,结果如下:
上面我们写的那个接口其实是写死的,他没有办法对参数进行一个接收和处理,这个和实际的情景也是不一样的。所以我要学习一下在springboot中,如果要对参数进行接收和处理的话要怎么做。
我们在上面的controller类中添加一个requestPara方法,把请求的参数给获取到,方法内用一个@RequestParam注解来表明传入的参数,并且可以对参数操作。
@GetMapping("para")
public String requestPara(@RequestParam Integer num){
return "我收到了参数:"+ num;
}
浏览器运行如下:
上面演示了GET请求接收请求传过来的参数,下面编写一个方法来演示接收POST请求传过来的参数。post请求接收参数,参数用@RequestBody注解标注,我们这里创建一个类类接受传过来的参数。我们新创建一个包entity,里面放实体类。我们在里面创建一个Student学生类,里面有id和name两个属性。
package com.haiexijun.springbootlearn.entity;
public class Student {
private Integer id;
private String name;
public Student(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
@PostMapping("/post")
public String postRequest(@RequestBody Student student){
return "我收到了post参数:"+ student;
}
本节对配置文件进行讲解。在springboot中,主要有两种配置文件。第一种是properties这种结尾了,是点来分层的,还有一种是yml结尾的配置文件,分行来分层。这两种配置选择一种就可以了。https://www.toyaml.com/index.html就可以把两种文件转换。
下面我们来学习一下,我们能配置哪些东西。打开application.properties这个文件,进行如下配置:
server.port=8081
spring.application.name="first-springboot"
server.servlet.context-path=/first
上面的server.port=8081表示设置项目启动后的端口号,spring.application.name="first-springboot"设置项目的名称,server.servlet.context-path=/first设置项目的上下文路径。
配置自定义属性:
关于自定义属性,会讲解下面几个内容。假设我们想要返回一个东西,但是我们不想把这个东西写在代码里面,因为写在代码里面相当于是一种写死的情况。
我们要使用到一个注解,就是@Value ,利用它,我们就可以把某些经常变的属性去把它配置到配置文件中,而不需把它写死到我们的代码中。
我们下面创建一个新的controller,假如我们要打印出年级和班级,如果写死的话,如下:
package com.haiexijun.springbootlearn.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PropertiesController {
Integer grade=5;
Integer classNum=9;
@GetMapping("gradeClass")
public String gradeClass(){
return "年级"+grade+"班级"+classNum;
}
}
这种写法有很大的弊端,写在代码里很不灵活。所以下面来用@Value来配置使用:
package com.haiexijun.springbootlearn.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PropertiesController {
@Value("${school.grade}")
Integer grade;
@Value("${school.classNum}")
Integer classNum;
@GetMapping("gradeClass")
public String gradeClass(){
return "年级"+grade+"班级"+classNum;
}
}
然后在配置文件中指定这两个属性:
school.grade=5
school.classNum=3
这个技巧是经常用到的,有的时候可能不是指定年级和班级,而是指定IP或一个路径什么的。都会使用到这个@value注解。
然后,我们在来看第二种情况,第二种情况他是静态的一种情况。我们添加一个静态变量age。再编写一个方法来测试:
@Value("${school.age}")
static Integer age;
@GetMapping("/static")
public String staticPara(){
return "静态变量的值"+age;
}
同时在配置文件中也添加上这个属性的值。
school.age=18
当我们访问时会发现age为null。
要怎么办呢,只要在当前静态属性的类下添加它的set方法,@Value写到set这个方法上就可以了。(注意:set方法的static要去掉)
static Integer age;
@Value("${school.age}")
public void setAge(Integer age) {
PropertiesController.age = age;
}
下面来写一个学生信息的一个查询的案例,这个学生信息主要包含学号或者叫id以及他的名字。我希望通过这个小型的案例,把整个springboot这个项目从controller到service,最后再到数据库的链路给打通。
我们想要引入一个和数据库相关的依赖:
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.3version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.25version>
dependency>
导入完依赖后,我们还要对配置文件进行编写:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=zc20020106
然后,我们创建一个mapper包,包下创建一个StudentMapper的接口,接口用@Mapper和@Repository注解进行标注。接口里面定义一个方法,方法上面再@Select注解里面书写select语句。数据库和表以及student实体类已经创建好了,这里就不做示范了。
package com.haiexijun.springbootlearn.mapper;
import com.haiexijun.springbootlearn.entity.Student;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface StudentMapper {
@Select("SELECT * FROM students WHERE id = #{id}")
public Student findById(int id);
}
然后,我们创建一个新的包叫做service包,里面创建一个StudentService类,我们用@Service来对类进行标注。
package com.haiexijun.springbootlearn.service;
import com.haiexijun.springbootlearn.entity.Student;
import com.haiexijun.springbootlearn.mapper.StudentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class StudentService {
@Autowired
StudentMapper studentMapper;
public Student getStudent(int id){
return studentMapper.findById(id);
}
}
接着,我们创建一个controller,编写如下代码:
package com.haiexijun.springbootlearn.controller;
import com.haiexijun.springbootlearn.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class StudentController {
@Autowired
StudentService studentService;
@GetMapping("/student")
public String requestPara(@RequestParam Integer id){
return studentService.getStudent(id).toString();
}
}
学到这里,springboot大概就入门了。接下来的话,我会通过做一个大型的springboot电商项目来深入学习springboot的更多高级功能。