目录
一、SpringBoot概述
二、使用springboot
二、配置文件详解
1. 属性配置文件
2. YAML配置文件?
3. 多环境profile切换配置
三、Spring Boot自动配置(理解)
条件化配置注解
四、自动配置原理
默认属性配置
五、自定义启动器?
六、Spring Data JPA
Spring Boot综合案例(应用)
1、环境搭建 (数据库、结构)
2、数据访问层
3、Service?业务层
4、Controller?表现层
一、SpringBoot概述
Spring Boot是Spring项目中的一个子工程,与我们所熟知的Spring-framework 同属于spring的产品。其最主要作用就是帮助开发人员快速的构建庞大的spring项目,并且尽可能的减少一切xml配置,做到开箱即用,迅速上手,让开发人员关注业务而非配置。 设计目的: 用来简化 Spring?应用的初始搭建以及开发过程。
(1)为所有 Spring 开发提供一个更快更广泛的入门体验。
(2)零配置。无冗余代码生成和XML 强制配置,遵循“约定大于配置,习惯优于配置” 。
(3)集成了大量常用的第三方库的配置, Spring Boot 应用为这些第三方库提供了几乎可以零配置的开箱即用的能力。
(4)提供一系列大型项目常用的非功能性特征,如嵌入服务器等。
主要特点:
- 自动配置?: 不需要再关注各个框架的整合配置, springboot全部已经配置好了
- 起步依赖?: 我们在需要使用某个框架的时候, 直接添加这个框架的启动器依赖即可 , 不需要在关注jar包的冲突和整合
二、使用springboot
1. pom.xml 添加父工程坐标、web启动器
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<groupId>com.atguigu</groupId>
<artifactId>springboot_01</artifactId>
<version>1.0</version>
<!--为什么我们在添加启动器的时候不需要添加版本?
答:父工程帮我们统一管理
-->
<!--添加父工程坐标-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.6.RELEASE</version>
</parent>
<!--
为什么我们就只添加了一个启动器依赖,项目就可以运行起来了,这些jar包从何而来?
答:引入启动器,间接依赖了很多jar包,从本地仓库进行依赖注入
-->
<!--添加web启动器,框架提供了很多启动器(起步依赖),其实就是一组jar包的名称
web启动器: 引入web开发相关的jar
-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!--可选,jdk版本-->
<properties>
<java.version>1.8</java.version>
</properties>
</project>
2. 创建启动类
Spring Boot项目通过main函数即可启动,我们需要创建一个启动类:
@SpringBootApplication //s声明当前项目是一个SpringBoot项目
public class App {
//启动内置的Tomcat服务器,即初始化Ioc容器(采用框架默认配置)
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}
3. 编写Controller
@RestController //相当于 @Controller + @ResponseBody
public class HelloController {
@RequestMapping("/hello")
public String sayHello(){
return "hello spring boot!!" ;
}
}
4. 启动测试
?
5. 问题
1、为什么我们在添加启动器的时候不需要在启动器的坐标中指定版本?
答案:因为我们指定了项目的父工程,在spring-boot-starter-parent中已经通过Maven的版本锁定了Jar包的版本,所以就不需要再指定了。
2、为什么我们就添加一个启动器依赖,项目就可以运行起来了,运行项目所需要的Jar包从何而来?
答案:因为我们添加了这个启动器的依赖,它已经把自己运行所需要的必要包集成在这个启动器中,通过Maven的依赖传递性,将这些包都依赖到咱们的项目里了。
二、配置文件详解
springboot支持二种类型的配置文件
配置文件必须放置在项目的类加载目录下, 并且名字必须是?application,springboot项目在运行的时候会自动加载这些配置文件
1. 属性配置文件
spring.jdbc.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.jdbc.datasource.url=jdbc:mysql://localhost:3306/db_house?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.jdbc.datasource.username=root
spring.jdbc.datasource.password=******
?新建?properties?包,创建类?DataSourceProperties?
package com.atguigu.properties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class DataSourceProperties {
// @Value 可以获取属性配置文件的属性值,无需get/set方法。缺点:需要一个一个获取
@Value("${spring.jdbc.datasource.driverClassName}")
private String driverClassName;
@Value("${spring.jdbc.datasource.url}")
private String url;
@Value("${spring.jdbc.datasource.username}")
private String username;
@Value("${spring.jdbc.datasource.password}")
private String password;
// 生成get set 和 toString方法
}
测试:
?成功注入
2. YAML配置文件?
YAML是一种配置文件格式,扩展名是?yaml 或 yml
1.数据结构用树形结构呈现,通过缩进来表示层级,
2.连续的项目通过减号 ” - ” 来表示
3.键值结构里面的key/value对用冒号 ” : ” 来分隔。
?spring:
??jdbc:
????datasource:
??????driverClassName:?com.mysql.jdbc.Driver
??????url:?jdbc:mysql:///springboot_01
??????username:?root
??????password:?root
yml配置文件的特征:
- 树状层级结构展示配置项;
- 配置项之间如果有关系的话需要分行,空两格;
- 配置项如果有值的话,那么需要在?:之后空一格再写配置项值;
3. 多环境profile切换配置
在Spring Boot项目中配置文件的名称只能是**application** , 如果我们把所有的配置项全都写在一个配置文件中, 配置文件就会比较复杂和臃肿,不利于后期的项目维护和开发。
1.因为开发环境的变化, 我们需要修改配置文件中某一个配置项的值(比如之前是mysql数据库,切换成oracle数据库)
2.项目开发完成需要上线了 , 需要把一些环境修改成正式环境(开发,测试,上线,多环境切换)
解决方案 :使用profiles拆分配置
spring boot项目中允许使用多个YAML配置文件。
这些文件名称必须为application-***.yml,并且在application.yml中激活。
spring:
profiles:
active: dev
?注意 :
如果properties和yml文件都存在,不存在spring.profiles.active设置,如果有重叠属性,默认以properties优先。
如果设置了spring.profiles.active,并且有重叠属性,以active设置优先。
可以在两种文件中分别增加server.port属性指定不同的端口,启动项目查看控制台端口号进行测试。
三、Spring Boot自动配置(理解)
@SpringBootApplication 注解
- @SpringBootConfiguration : 代表这个类就是一个配置类 , 本质上就是一个@Configuration注解
- @EnableAutoConfiguration : 自动配置注解 , 添加了此注解会自动去读取spring.factories配置文件中的自动配置类
- @ComponentScan : 组件扫描, 默认扫描启动类所在包及子包下的类身上的注解
@ConfigurationProperties(prefix = "xxx") 注解
报错提示,请在pom文件添加配置信息即可(不影响运行)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
@Value 一个个注入?
// @Value 可以获取属性配置文件的属性值,无需get/set方法。缺点:需要一个一个获取
@Value("${spring.jdbc.datasource.driverClassName}")
private String driverClassName;
@Value("${spring.jdbc.datasource.url}")
private String url;
@Value("${spring.jdbc.datasource.username}")
private String username;
@Value("${spring.jdbc.datasource.password}")
private String password;
条件化配置注解
注解 | 作用 | @ConditionalOnBean | 如果存在某个Bean, 配置类生效 | @ConditionalOnMissingBean | 如果不存在某个Bean, 配置类生效 | @ConditionalOnClass | 如果存在某个类, 配置类生效 | @ConditionalOnMissingClass | 如果不存在某个类, 配置类生效 | @ConditionalOnProperty | 如果存在某个属性配置, 配置类生效 | @ConditionalOnWebApplication | 如果是一个web应用, 配置类生效 | @ConditionalOnNotWebApplication | 如果不是一个web应用, 配置类生效 |
@RestController //相当于 @Controller + @ResponseBody
//启用属性配置类,带@ConfigurationProperties属性的类要先生效
@EnableConfigurationProperties(value = {DataSourceProperties.class})
public class HelloController {
@Autowired
DataSourceProperties dataSourceProperties;
@RequestMapping("/hello")
public String sayHello(){
System.out.println(dataSourceProperties);
return "hello spring boot!!" ;
}
}
四、自动配置原理
@SpringBootApplication //声明当前项目是一个SpringBoot项目
public class App {
//启动内置的Tomcat服务器,即初始化Ioc容器(采用框架默认配置)
public static void main(String[] args) {
/*
* 自动配置初始化过程:
* 1.从加载jar包中查找META-INF/spring.factories文件,构造出一些工厂对象,来初始化总起
* 2.会查找org.springframework.boot.autoconfigure.EnableAutoConfiguration名称的值。
* 获取了127个配置类。
* Springboot框架与其他框架继承,提供大量配置类,简化了框架集成过程。可以提高开发效率
* 例如: 引入了spring-boot-starter-web启动器
* HttpEncodingAutoConfiguration 自动配置字符编码过滤器.相当于web.xml配置,默认utf-8
* MultipartAutoConfiguration 文件上传解析器
* WebMvcAutoConfiguration 负责创建视图解析器
* DispatcherServletAutoConfiguration 负责创建核心控制器
*
*
* */
SpringApplication.run(App.class,args);
}
}
彩蛋 :英姿飒爽的张宇老师
?
?在SpringApplication类构建的时候,有这样一段初始化代码:
?跟进去往下走
?这里发现会通过loadFactoryNames尝试加载一些FactoryName,然后利用createSpringFactoriesInstances将这些加载到的类名进行实例化。 继续跟进loadFactoryNames方法:?发现此处会利用类加载器加载一个文件:?META-INF/spring.factories?。我们知道,ClassLoader默认是从classpath下读取文件,因此,SpringBoot会在初始化的时候,加载所有classpath:META-INF/spring.factories文件,包括jar包当中的。而在Spring的一个依赖包:spring-boot-autoconfigure中,就有这样的文件:
我们引入的任何第三方启动器,只要实现自动配置,也都会有类似文件。
打开后,可以发现以EnableAutoConfiguration接口为key的一系列配置,key所对应的值,就是所有的自动配置类,可以在当前的jar包中找到这些自动配置类,几乎涵盖了现在主流的开源框架
默认属性配置
配置类我们找到了 , 那么这些默认配置的属性来自哪里呢?
例如 : 我们配置视图解析器的时候需要配置前缀和后缀 , 那么这些配置在哪配置的呢 ?
通过源码发现, 这个配置是从this.mvcProperties.getView()中读取的 ,this.mvcProperties又是什么呢 ? 我们继续跟踪,发现其实就是定义的一个变量
?这个变量中又有一个View类型的变量 , 这个变量中配置的就是前缀和后缀,默认为null??
一、自定义启动器?
定义一个连接池启动器 , 当用户引入了连接池启动依赖之后 , 项目中就已经自动配置了连接池
1、开发启动器。2、使用启动器
1.?引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<groupId>com.atguigu</groupId>
<artifactId>spring-boot-jdbc-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.6.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--引入spring‐boot‐starter;所有starter的基本配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--自动配置连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
2.?创建属性配置类
package com.atguigu.autoconfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
//属性配置类
@Component
@ConfigurationProperties(prefix = "spring.jdbc.mydatasource") //由使用者提供
public class MyDataSourceProperties {
private String driverClassName ;
private String url;
private String username;
private String password;
// 生成set get toString方法
}
3.?创建自动配置类?
//数据源配置类: 用于创建数据源
//@Configuration
@SpringBootConfiguration //声明配置类,等价于@Configuration
@EnableConfigurationProperties(value = {MyDataSourceProperties.class})
public class DataSourceAutoConfiguration {
@Autowired
MyDataSourceProperties myDataSourceProperties;
@Bean
@ConditionalOnProperty(value = "spring.jdbc.mydatasource.type",havingValue = "druid")
public DataSource createDataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(myDataSourceProperties.getDriverClassName());
dataSource.setUrl(myDataSourceProperties.getUrl());
dataSource.setUsername(myDataSourceProperties.getUsername());
dataSource.setPassword(myDataSourceProperties.getPassword());
System.out.println("自定义启动器生效了! druid");
return dataSource;
}
@Bean //声明数据源bean对象 相当于spring-dao.xml中声明的<bean对象>
@ConditionalOnProperty(value = "spring.jdbc.mydatasource.type",havingValue = "c3p0")
public DataSource createC3P0DataSource() throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(myDataSourceProperties.getDriverClassName());
dataSource.setJdbcUrl(myDataSourceProperties.getUrl());
dataSource.setUser(myDataSourceProperties.getUsername());
dataSource.setPassword(myDataSourceProperties.getPassword());
System.out.println("自定义启动器生效了! c3p0");
return dataSource;
}
}
4.?编写自动配置属性文件
在?resources?文件夹下面新建?META-INF/spring.factories,
做完了之后注意要执行install , 安装项目
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.atguigu.autoconfig.DataSourceAutoConfiguration
使用自定义启动器
1. 引入依赖
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>spring-boot-jdbc-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
2.?配置连接池信息
application-dev.yml
spring:
jdbc:
mydatasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://myDataSource
username: dev
password: dev
type: c3p0
#激活配置文件
spring:
profiles:
active: dev
3. 注入连接池, 查看连接池属性
@RestController //相当于 @Controller + @ResponseBody
//启用属性配置类,带@ConfigurationProperties属性的类要先生效
@EnableConfigurationProperties(value = {DataSourceProperties.class})
public class HelloController {
@Autowired
DataSourceProperties dataSourceProperties;
@Autowired
MyDataSourceProperties myDataSourceProperties;
@RequestMapping("/hello")
public String sayHello(){
System.out.println("dataSource:"+myDataSourceProperties);
System.out.println(dataSourceProperties);
return "hello spring boot!!" ;
}
}
|