springboot和spring一样,是和其他技术进行整合的一种技术。
Spring是Java企业版的轻量级代替品。Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象实现了EJB的功能。
spring在开发过程中可以把相应的bean配置到配置文件当中,通过IOC让spring容器来进行管理Java对象。减少代码的工作,还能减少层与层之间的耦合。
虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。一开始,Spring用XML配置,而且是很多XML配置。
Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。
Spring 3.0引入了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML,全注解的配置方式。
所有这些配置都代表了开发时的损耗。因为在思考Spring特性配置和解决业务问题之间需要进行思维切换,所以编写配置挤占了编写应用程序逻辑的时间。和所有框架一样,Spring实用,但与此同时它要求的回报也不少。
除此之外,项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。
SpringBoot对上述Spring的缺点进行的改善和优化,基于约定优于配置的思想,也就是说在spring开发的过程中,需要人告诉这个框架需要怎么做,但是告诉框架需要做的事情有时候都是一样的,这样的话就需要把这些配置设置为默认的,这样在开发的过程中不需要开发人员过多的关注配置文件的配置,只需要进行业务逻辑代码的编写就行。
其实springBoot的核心功能就是上面提到的所有的springBoot 的特点。
起步依赖
起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。
简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。
自动配置
Spring Boot的自动配置是一个运行时(更准确地说,是应用程序启动时)的过程,考虑了众多因素,才决定Spring配置应该用哪个,不该用哪个。该过程是Spring自动完成的。在程序中我们需要使用一个sessionFactory的时候我们需要在我们的spring中配置一个sessionFactory,mybaties和hibernate都有相关的配置,但是sessionfactory配置的时候需要一个数据源datasource,按照spring的做法,这个数据源需要配置,需要的时候再注入DataSource ,但是springboot提供了一种可以自动的把数据源注入到DataSource当中,这样可以让你直接的使用。
关于起步依赖和自动配置的具体用法在下面的代码中会进一步的详细讲解。
springboot的底层抵赖与spring framework ,spring framework是一种Javaee的框架,springboot是一种快速构建spring应用的框架,然后spring cloud 是一种构建spring boot的分布式的应用 底层依赖于springboot 三个角色相互相成 ,spring boot起到一个承上启下的作用。
编程语言需要用 Java8 底层的框架时spring framework 5.0X
使用idea工具创建一个maven工程,该工程为普通的java工程即可
SpringBoot要求,项目要继承SpringBoot的起步依赖spring-boot-starter-parent
也就是在创建springboot工程的时候,所有的项目都需要是parent的子才行。
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.1.RELEASEversion>
parent>
SpringBoot要集成SpringMVC进行Controller的开发,所以项目要导入web的启动依赖
我们需要在这里需要在页面上看到效果,所以需要导入一个web项目的起步依赖,我们需要开发web工程只需要导入这个起步依赖就可以。
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
这个坐标的底层负责导入spring和springMVC的各种坐标,所以我们只需要导入这一个就可以了。
导入之后在项目中完整的pom文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.1.RELEASEversion>
parent>
<groupId>cn.zzugroupId>
<artifactId>springboot_quickartifactId>
<version>1.0-SNAPSHOTversion>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
project>
到这配置完事了
但是还缺少一个引导类的编写。
编写引导类:名字任意
package cn.zzu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
//标注一下这个类是springboot的引导类
public class MyspringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MyspringBootApplication.class);
}
}
SpringBootApplication注解在哪个类上哪个类就是引导类。假如我们在另一个类中加上 @SpringBootApplication注解,那么这个xxx类就是引导类。
例如我们在run方法中写入字节码文件就可以,SpringApplication.run(xxx.class);
这样也能正确的加载引导类。
运行之后打印出spring以及一片的日志信息
. ____ ___ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::(v2.0.1.RELEASE)
2019-09-07 10:12:33.953 INFO 136952 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-09-07 10:12:33.956 INFO 136952 --- [ main] cn.zzu.MyspringBootApplication : Started MyspringBootApplication in 4.653 seconds (JVM running for 7.3)
从这一段日志中我们可以发现,Tomcat的端口已经启动了,端口是8080 说明是已经内置了Tomcat 项目的访问路径是空的
我们通过localhost:8080访问Tomcat,然后会打印出一下的信息
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
说明我们还没有配置任何项目
下面我们写一个controller来进行测试一下
编写controller
QuickController.Java
package cn.zzu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class QuickController {
@RequestMapping("/quick")
@ResponseBody
public String quick(){
return "hello springboot";
}
}
这个时候运行我们的项目。 然后访问 localhost:8080/quick
这个时候就会显示出我们编写的一个简单的输出 hello springboot
到这里我们就可以发现,一个简单的springboot项目的跑通,一种经历了三步,添加起步依赖,编写引导类,然后编写controller
我们没有编写任何配置文件,没有做任何关于springMVC和spring的配置我们就可以直接使用注解的方式来创建一个简单的springboot的程序。
我么可以发现我们添加的起步依赖帮我们添加了一个springMVC的坐标,如果没有添加,上面的注解是无法使用的。
在上面的配置文件中,所有的springboot工程都必须依赖 spring-boot-starter-parent
我们导入web的起步依赖spring-boot-starter-web会帮我们自动的添加关于spring以及springMVC的各项依赖。
我们在开发中反复修改类、页面等资源,每次修改后都是需要重新启动才生效,这样每次启动都很麻烦,浪费了大量的时间,我们可以在修改代码后不重启就能生效,在 pom.xml 中添加如下配置就可以实现这样的功能,我们称之为热部署。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
dependency>
注意:这样在工程中设置过之后,可能还是会出现无法进行热部署的原因,我们需要在idea中进行设置,开启热部署
出现这种情况,并不是热部署配置问题,其根本原因是因为Intellij IEDA默认情况下不会自动编译,需要对IDEA进行自动编译的设置
勾选setting中 build auto。。选项
然后按 ALT+SHIFT+CTRL+/ 选择 register 勾选 compiler.automake.allow.running 选项就可以进行热部署了
我们可以在创建项目的时候选择 Spring Initializr 来进行springBoot项目的自动创建
然后会自动把工程需要的坐标全都导入项目中,而且还会在项目文件夹下自动创建引导类
starter-parent的底层主要是对版本控制之类的坐标配置
从spring-boot-starter-dependencies的pom.xml中我们可以发现,一部分坐标的版本、依赖管理、插件管理已经定义好,所以我们的SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了。所以起步依赖的作用就是进行依赖的传递。
按住Ctrl点击pom.xml中的spring-boot-starter-web,跳转到了spring-boot-starter-web的pom.xml,xml配置如下(只摘抄了部分重点配置):
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-startersartifactId>
<version>2.0.1.RELEASEversion>
parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<version>2.0.1.RELEASEversion>
<name>Spring Boot Web Startername>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
<version>2.0.1.RELEASEversion>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jsonartifactId>
<version>2.0.1.RELEASEversion>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
<version>2.0.1.RELEASEversion>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.hibernate.validatorgroupId>
<artifactId>hibernate-validatorartifactId>
<version>6.0.9.Finalversion>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>5.0.5.RELEASEversion>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.0.5.RELEASEversion>
<scope>compilescope>
dependency>
dependencies>
project>
从上面的spring-boot-starter-web的pom.xml中我们可以发现,spring-boot-starter-web就是将web开发要使用的spring-web、spring-webmvc等坐标进行了“打包”,这样我们的工程只要引入spring-boot-starter-web起步依赖的坐标就可以进行web开发了,同样体现了依赖传递的作用。
SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(application.yaml)进行配置。
SpringBoot默认会从Resources目录下加载application.properties或application.yml(application.yaml)文件
其中,application.properties文件是键值对类型的文件,之前一直在使用,所以此处不在对properties文件的格式进行阐述。除了properties文件外,SpringBoot还可以使用yml文件进行配置,下面对yml文件进行讲解。
YML文件格式是YAML (YAML Aint Markup Language)编写的文件格式,YAML是一种直观的能够被电脑识别的的数据数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,比如: C/C++, Ruby, Python, Java, Perl, C#, PHP等。YML文件是以数据为核心的,比传统的xml方式更加简洁。
YML文件的扩展名可以使用.yml或者.yaml。
主要讲解两种配置方式,一种是配置普通数据,一种是配置对象数据。
语法: key: value
示例代码:
name: haohao
注意:value之前有一个空格,空格后面才能写value
server:
port: 8081
注意:如果我们在这里配置了两个一个是application.properties一个是application.yml文件。加载的顺序是先加载application.yml文件
语法:
key:
key1: value1
key2: value2
或者:
key: {key1: value1,key2: value2}
示例代码:
#对象的配置
yaml
person:
name: xiaoming
age: 31
addr: beijing
#或者
person: {name: haohao,age: 31,addr: beijing}
- 注意:key1前面的空格个数不限定,在yml语法中,相同缩进代表同一个级别
##### 4.1.2.2.2 配置Map数据
同上面的对象写法
##### 4.1.2.2.3 配置数组(List、Set)数据
- 语法:
key:
- value1
- value2
或者:
key: [value1,value2]
- 示例代码:
- ```yaml
city:
- beijing
- tianjin
- shanghai
- chongqing
#或者
city: [beijing,tianjin,shanghai,chongqing]
#集合中的元素是对象形式
student:
- name: zhangsan
age: 18
score: 100
- name: lisi
age: 28
score: 88
- name: wangwu
age: 38
score: 90
```
- 注意:value1与之间的 - 之间存在一个空格
**
我们在以上的问价中我们配置properties文件或者是yml文件时,像我们配置的server这些端口数据,配置文件会自动的识别的,但是配置的student数据,或者其他的对象数据配置文件是不会自动识别的,所以就需要我们进行文件的识别映射**
## 4.2 配置文件与配置类的属性映射方式
配置类的属性映射我们可以通过@Value 映射 来进行获取
### 4.2.1 使用注解@Value映射
我们可以通过@Value注解将配置文件中的值映射到一个Spring管理的Bean的字段上
例如:
application.properties配置如下:
```properties
person:
name: zhangsan
age: 18
```
或者,application.yml配置如下:
```yaml
person:
name: zhangsan
age: 18****
```
实体Bean代码如下:
```java
package cn.zzu.Controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class Quick2Controller {
@Value("${person.name}")
private String name;
@Value("${person.age}")
private Integer age;
@RequestMapping("/quick3")
@ResponseBody
public String quick(){
return "springboot 访问成功! name="+name+",age="+age;
}
}
浏览器访问地址:http://localhost:8080/quick3 既可以进行结果的输出
我们使用这种方式获取值的时候优点是获取的值比较精确,可以获取到我们想获取的信息,但是缺点是比较繁琐,如果只有几个信息的时候可以通过这种方式获取,但是如果信息比较多的时候,就比较耗费时间。这时,我们可以使用,使用注解@ConfigurationProperties映射
通过注解@ConfigurationProperties(prefix=“配置文件中的key的前缀”)可以将配置文件中的配置自动与实体进行映射
application.properties配置如下:
```properties
person:
name: zhangsan
age: 18
```
或者,application.yml配置如下:
```yaml
person:
name: zhangsan
age: 18
```
JavaBean代码如下:
package cn.zzu.Controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@ConfigurationProperties(prefix = "person")
public class Quick3Controller {
private String name;
private Integer age;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
@RequestMapping("/quick4")
@ResponseBody
public String quick(){
return "springboot 访问成功! name="+name+",age="+age;
}
}
这个时候如果没有配置ConfigurationProperties会提示一个 错误,我们需要添加依赖消除这种错误提示
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
注意:使用@ConfigurationProperties方式可以进行配置文件与实体字段的自动映射,但需要字段必须提供set方法才可以,而使用@Value注解修饰的字段不需要提供set方法
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.1.1version>
dependency>
这个起步依赖是mybaties提供的
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
在application.properties中添加数据量的连接信息
#DB Configuration:
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
我们在配置文件中添加数据库的连接信息。
在test数据库中创建user表
-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'zhangsan', '123', '张三');
INSERT INTO `user` VALUES ('2', 'lisi', '123', '李四');
package cn.zzu.springboot_mybaties.domain;
public class User {
// 主键
private Long id;
// 用户名
private String username;
// 密码
private String password;
// 姓名
private String name;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", name='" + name + '\'' +
'}';
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
我们把数据库和我们的实体对应起来, 需要编写mapper
@Mapper
public interface UserMapper {
public List<User> queryUserList();
}
注意:@Mapper标记该类是一个mybatis的mapper接口,可以被spring boot自动扫描到spring上下文中
在src\main\resources\mapper路径下加入UserMapper.xml配置文件"
<mapper namespace="cn.zzu.springboot_mybaties.mapper.UserMapper">
<select id="queryUserList" resultType="user">
select * from user
select>
mapper>
#spring集成Mybatis环境
#pojo别名扫描包
mybatis.type-aliases-package=cn.zzu.springboot_mybaties.domain
#加载Mybatis映射文件
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
package cn.zzu.springboot_mybaties.controller;
import cn.zzu.springboot_mybaties.domain.User;
import cn.zzu.springboot_mybaties.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
public class MybatiesController {
@Autowired
private UserMapper userMapper;
@RequestMapping("/query")
@ResponseBody
public List<User> queryUser(){
List<User> users = userMapper.queryUserList();
return users;
}
}