SpringBoot 2.3.5
之前ssm开发面临的问题:
- 在ssm整合的时候,面临了大量的固定的一些配置,特别和其他功能整合的时候,也需要配置。
- 在ssm整合的时候,版本管理,需要在父工程中写很多版本
- 整合第三方功能的时候,有时候,不知道该配置什么 javaMailSender…
SpringBoot
是一个全新的框架、2017年年底开始在国内流行起来
作用:
1、快速开发,让程序员不用关注过多的配置,只需要关注业务逻辑即可
SpringBoot的四大核心
1、起步依赖(starter):springBoot把很多的功能能够独立运行的最小jar包依赖一个一个封装成 stater,我们只需要依赖starter即可
2、自动配置:做某一个功能,添加这个功能的起步依赖,就可以直接写代码,需要的配置 有默认的(这个默认的就是springboot帮你做好的配置)
3、监控:SpringBoot 项目 可以通过监控看到springBoot 项目运行的流程 springboot admin
4、命令行:…
SpringBoot官网 (2.3.5版本)
SpringBoot更新很快
SpringBoot项目的环境要求:
Java8 以及以上 (11将会缺少jax包)
maven 3.3
tomcat9
SpringBoot项目的搭建(两种方式)
1、搭建普通的maven工程
-
创建一个普通的maven工程
-
根据官网在pom.xml文件中导入
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
-
编写一个类 一般叫做 XXXApplication
1、在类上添加一个注解
2、编写一个main方法
@SpringBootApplication
public class ProjectApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectApplication.class, args);
}
}
- 编写controller
@RestController
public class HelloController {
@GetMapping("hello")
public String hello(){
return "hello SpringBoot";
}
}
2、使用骨架创建(2020.2这个版本有问题)
-
创建项目 选择 spring initxxx
-
进入页面 勾选springboot版本 勾选想要的功能(自动导入依赖)
删除没用的之后还剩下:
好处:
自动导入勾选的依赖 自动创建 xxxApplication类 把包补全
缺点:
无法自定义springboot版本、生成一些无用的文件
springboot的简单创建发现的问题
1、创建的是普通的maven工程 默认打包方式是 jar
运行的是main 并没有配置tomcat 为什么启动的是8080呢
- SpringBoot把tomcat内置了 SpringBoot本身依赖了内置的tomcat
2、在依赖中 并没有依赖 web MVC 也没有核心4+1
3、返回对象直接返回来json 然后依赖并没有jackson ,并且jdk8格式的也生效了(loacldatetime也是直接返回,并没有依赖 jsr 3.0)
- 起步依赖中已经包含了这些依赖
项目分析:
pom.xml
parent标签:这个标签可以省略(版本要放到dependecies中),一般不要省略
- 功能:做版本管理、父工程的父工程中定义了大量经常使用的依赖的版本号。所以在 依赖这些依赖时候不需要写版本号,但是springboot中没有版本定义的依赖,还是需要手写版本号,比如:mybatis
- 父工程指定了jdk版本 utf-8等
这个就是springboot封装的一个web层的起步依赖,这个依赖中 包含启动web工程的最基础的功能
springboot封装的起步依赖有很多,他们有一个共同点:名字都叫做:spring-boot-stater-xxx
xxxApplication
@SpringBootApplication
public class MyBootApplication {
public static void main(String[] args) {
SpringApplication.run(MyBootApplication.class);
}
}
这个注解是一个组合注解:
@SpringBootApplication
@SpringBootApplication
这个注解标注在类上,就代表这个类是springboot的主配置类(入口类)、
1、@SpringBootConfiguration
- 1.1、@Configuration
- 1.1.1、@Component
2、@EnableAutoConfiguration
- 2.1、@AutoConfigurationPackage
- 2.1.1、@Import({Registrar.class})
- 2.2、@Import({AutoConfigurationImportSelector.class})
-@SpringBootConfiguration :
这个注解就是建立在spring的configuration注解上的,和configuration一样。标注在类上,说明这个类是配置类,还在容器中
--@Configuration
---@Component
-@EnableAutoConfiguration:开启自动配置
这个注解也是一个组合注解:
--1、@AutoConfigurationPackage:自动配置包,配置的是 @SpringBootApplication这个注解所在类所在的包(类似包扫 描,可以扫描这个包和他的子包)
---1.1、@Import({Registrar.class})
--2、@Import({AutoConfigurationImportSelector.class})
作用就是加载spring-boot-autoconfigure-2.3.5.RELEASE.jar 项目下META-INF中spring.factories里面配置的字符串(这些字符 串是某一个类的完整路径),并且这些类的类名 很统一 都叫 xxxAutoConfiguration
加载这些类就是做自动配置的
springboot的配置文件(两种格式)
- properties文件 -->application.properties
- yml(yaml)文件 -->application.yml
名字叫做 application --springboot会自动加载
配置文件可以修改端口,存值
配置文件中可能存在乱码问题,修改设置为files-Encoding:utf-8即可
取properties的值
1、普通类型和字符串
key=value
2、对象或者map
key=value
key.field=value 如果使用这种方式 是有前缀的
3、lsit集合
key=value1,value2,value3
(key可使用前缀,取值时候注意指定前缀)
取值:
- @Value("${key}")直接取值
- 封装到对象类中(key和对象的属性对应/在这个对象类中使用Map)这个对象要在容器中(@Component)
@ConfigurationProperties(prefix = “前缀”)
注意点:
- @Value("${key}") 不依赖set方法
- @ConfigurationProperties需要依赖 set方法
application.yml
语法:key: value :和value之间需要一个空格
集合的写法(两种)
lsit集合建议使用 对象接收
配置文件中的其他内容(占位符和默认值)
如果两个配置文件同时存在
两个配置文件都会被加载,properties文件优先级比较高。如果两个文件中有相同的配置,则默认使用的是优先级高的properties文件中的配置。都被加载的时候优先级低的yml文件先被加载、优先级高的properties文件后加载。
配置文件的位置:
项目内(4个位置)
1、项目下的config目录下
2、项目下
3、resources下config目录下
4、resources下
优先级低的先被加载,配置文件中有相同的配置,会使用优先级高(后被加载)的文件
以上配置文件的位置,优先级依次降低,最下面的最先被加载。
四个配置文件都会被加载,如果有相同的配置,默认使用优先级最高的
注意点:在这四个位置中,前两个没有用,因为他们在项目路径下,之所以在运行时有用,时因为在开发工具中运行的。 如果打包项目,是不会打包到的,只会打包src中的
这4个配置文件都在项目中。
项目外
如果项目打成了jar包,如果想要修改配置,有如下几种配置
1、修改命令行参数
2、修改虚拟机参数
java -jar xxx.jar -Dserver.port=9988
3、定义一个配置文件 和 jar包放在同一个目录 启动jar 包时会替换(推荐使用)
打成jar包 cmd启动(在文件夹内启动cmd)
java -jar xxx.jar
加载外部配置文件(可以单独加载也可以封装成对象在加载)
@PropertySource("classpath:db.properties")
加载的properties文件
demo:
db.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:8080
DB
@Component
@ConfigurationProperties
public class DB {
private String driverClassName;
private String url;
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "DB{" +
"driverClassName='" + driverClassName + '\'' +
", url='" + url + '\'' +
'}';
}
}
DbController
@RestController
@PropertySource("classpath:db.properties")
public class DbController {
/*@Value("${driverClassName}")
private String driverClassName;
@Value("${url}")
private String url;*/
@Autowired
private DB db;
@GetMapping("db")
public String test(){
/*System.out.println(driverClassName);
System.out.println(url);*/
System.out.println(db);
return "ok--db";
}
}
Springboot如何把一个类放到容器中
1、注解@Component (前提是:这个类是自己编写的)
2、@Configuration+@Bean
如果是springboot 就在带@SpringBootApplication注解的主配置类中,在方法上添加@Bean。还可以和spring一样新建一个类@Configuration,方法上上添加注解@Bean
3、xml配置文件
标签
在(主)配置类中加载xml配置(spring配置文件)文件:@ImportResource("classpath:applicationContext.xml")
如何知道配置文件(application.properties/yml)该配置那些东西(三种方式)
比如端口号的修改,redis等该如何去配置?
解决方案:
1、靠IDEA提示
2、查官网
3、掌握自动配置原理:
自动配置原理
在External Libraries下的spring-boot-autoconfigure下的META-INF下的spring.factories文件里。存在很多 XXXAutoConfiguration
项目启动的时候,会加载一些 XXXAutoConfiguration, XXXAutoConfiguration就表示自动配置。会帮我们配置一些开发中需要配置的内容,并且在每一个XXXAutoConfiguration中都会有XXXProperties(如:RedisProperties),在这个properties类中的属性就是我们可以在配置文件中配置的内容。
思想就是在配置文件中编写对应的配置的时候,就去找到对应的XXXAutoConfiguration,然后找到XXXProperties,进去查看能够配置的内容即可。如果不配置,会有默认值。
编写代码的时 需要用的内容 也要去查看XXXAutoConfiguration,在这个类中会有编码时候需要的自动配置,如果你不手动配置,就会使用默认的配置,如果你手动配置了就使用你的自己的配置。
springboot是怎么判断你有没有配置的呢?
@Conditional 这个注解是spring的一个条件注解 它有很多延伸注解
@ConditionalOnClass({XXX.class}) :这个注解表示 如果有XXX.class这个类。被这个注解标记的类才生效
@ConditionalOnMissingBean 表示当你的容器中没有这个Bean的时候 被这个注解标注的才会生效。如果你自己写了,他就不生效了,用你自己写的。
当使用了一个web起步依赖之后,spring、springMVC的功能都可以使用了
那么持久层呢?
-
JDBC
-
spring-jdbc ->JdbcTemplate
-
SSM的步骤
- 1、需要依赖spring的环境
- 2、导入依赖:spring-jdbc spring-tx mysql-connector-java
- 3、配置数据源
-
SpringBoot的步骤
-
导入起步依赖:spring-boot-starter-data-jdbc
-
引入mysql-connector-java (不修改版本默认是8,注意时区问题)
-
配置数据源(application.yml)
# 配置数据源信息 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/boot_test?characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: 666
-
编写和数据库对应的实体类
-
编写Dao层和DaoImpl
-
Dao
public interface EmployeeDao { List<Employee> findAll(); Employee findById(Long id); void add(Employee employee); void update(Employee employee); void delete(Long id); }
-
DaoImpl
package com.codeyancy.cn.dao.impl; @Repository public class EmployeeDaoImpl implements EmployeeDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public List<Employee> findAll() { List<Employee> employees = jdbcTemplate.query("select * from employee", new BeanPropertyRowMapper<>(Employee.class)); return employees; } @Override public Employee findById(Long id) { Employee employee = jdbcTemplate.queryForObject("select * from employee where employee_id = ?", new BeanPropertyRowMapper<>(Employee.class), id); return employee; } @Override public void add(Employee employee) { jdbcTemplate.update("insert into employee (employee_name,employee_img,employee_email,employee_dept,employee_time) values (?,?,?,?,?)", employee.getEmployeeName(), employee.getEmployeeImg(), employee.getEmployeeEmail(), employee.getEmployeeDept(), employee.getEmployeeTime()); } @Override public void update(Employee employee) { jdbcTemplate.update("update employee set employee_name=?,employee_img=?,employee_email=?,employee_dept=?,employee_time=? where employee_id=?", employee.getEmployeeName(), employee.getEmployeeImg(), employee.getEmployeeEmail(), employee.getEmployeeDept(), employee.getEmployeeTime(), employee.getEmployeeId()); } @Override public void delete(Long id) { jdbcTemplate.update("delete from employee where employee_id =?", id); } }
-
编写service和serviceImpl
-
编写Controller
-
-
-
Mybatis
- xml配置的方式
- 注解的方式
-
mybatis-plus
SpringBoot集成测试
SSM集成测试:
- 导入 spring-test包 +junit包
- 编写测试类
- 在测试类上添加注解
- @RunWith(SpringRunner.class)
- @ContextConfiguration(locations = {“classpath:applicationContext.xml”})
- @Test直接写方法
SpringBoot集成测试
-
导入起步依赖spring-boot-starter-test,排除engine
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency>
-
在test文件夹下编写测试功能
-
第一种:随便写
- 在test文件夹下随便定义一个类,在这个类上添加注解@SpringBootTest(classes = MyApplication.class) 指定主配置类
-
第二种:按照规则写
-
测试类的包要和主配置类的包路径保持一致
-
测试类的类名是主配置类的类名加上 Tests
@SpringBootTest class Springboot2ApplicationTests { @Autowired private EmployeeDao employeeDao; @Test void contextLoads() { System.out.println(employeeDao.findById(12L)); } }
-
-
Springboot的起步依赖中不包括Druid, 如果想要使用,需要去mavenres 中找到 需要导入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
引入之后如何使用:
springboot整合mybatis的xml写法
1、添加起步依赖和数据库驱动
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2、编写mapper接口,然后对mapper接口进行扫描
第一种方式:在mapper接口中添加==@Mapper==注解
第二种方式:在配置类(xxxApplication)上 添加 @MapperScan 指定包即可(推荐使用)
@MapperScan(basePackages = "com.codeyancy.cn.mapper")
3、编写mapper对应的映射文件
4、编写对应的service
5、编写对应的controllerj进行测试
映射文件位置
1、如果按照规范写,在resources下建包,和mapper接口同包同目录,就会自动加载 不用管
2、如果不按照规范(不同包同目录)
解决方案:
2.1 直接在主配置文件(application.yml)中进行加载 mybatisMapperlocation
mybatis:
mapper-locations: classpath:目录名/*.xml
2.2使用mybatis-config.xml加载,然后springboot再去加载mybatis-config文件
- 2.2.1 mybatis-config.xml
- 2.2.2 application.yml去加载 mybatis-config.xml
springboot整合mybatis注解开发
- 注意包扫描MapperScan
- 在主配置类中开启事务
@EnableTransactionManagement
,在servcieImpl中添加注解@Transactional
springboot默认没有开启驼峰命名
spirngboot开启驼峰命名四种方式:
1、在mybatis-config.xml中开启驼峰命名,然后再application.yml中加载mybatis-onfig配置文件
2、直接在application.yml中配置(建议使用)
# 开启驼峰命名
mybatis:
configuration:
map-underscore-to-camel-case: true
3、在主配置类XXXApplication
中添加一个Bean ,开启驼峰命名
@Bean
public ConfigurationCustomizer configurationCustomizer(){
return new ConfigurationCustomizer() {
@Override
public void customize(Configuration configuration) {
configuration.setMapUnderscoreToCamelCase(true);
}
};
}
关于日期格式问题
- 如果实体类的日期格式为
Date
,在application.yml中配置自己想要的格式即可
spring
jackson:
date-format: yyyy-MM-dd HH:mm:ss
- 如果实体类的日期格式为
LocalDateTime
,使用上面的方式则不会生效,需要在实体类的属性上添加注解
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime employeeTime;
SpringBoot日志
日志的门面(日志的接口)
JCL Slf4J JBoss
日志的实现
log4j log4j2 commons-logging logback
日志打印只有接口是 不行的
由于springboot已经默认 slf4j 作为日志接口 那么如果想要使用其他日志打印,中间就需要 转换包 才行
如果想要有日志打印,必须要有实现
springboot使用的是 slf4j+logback
mybatis 用的是 log4j
1、日志等级相关
TRACE DEBUG INFO WARN ERROR
从左到右 日志等级越来越高,比如默认级别是INFO 只会打印INFO和比它级别高的日志
默认等级
SpringBoot默认日志级别是 INFO
修改等级(在主配置(application.yml)文件中)
有一个关键字 root 表示修改整个项目的日志等级 为debug
修改指定包的日志的等级即可(查看mapper中sql执行时的打印debug)
2、日志入盘
默认情况下 ,springboot的日志只到控制台,需要入盘的话需要在主配置文件(application.yml)设置(2中方法)
日志大小(max-size)默认最大10MB,过了10MB以后会生成带数字的后缀的日志文件,也可以修改
logging:
file:
name: F:\\xxx.log 这种方式需要指定日志文件的位置和文件名 后缀必须是log
logging:
file:
path: F:\\ 指定日志文件的位置 只需要指定到文件夹即可,默认生成一个 spring.log 的文件
实际开发中,不需要配置以上的logging file… 不需要关注过多,只需要在网上找到一个 logback.xml文件 扔进resources文件夹下,注意修改log存放的路径即可。
3、修改日志的显示格式
SpringBoot静态资源问题
SpringBoot也是一个web项目,之前静态资源都是放在 webapp下的。现在没有webapp文件夹。那么静态资源应该放在那里?
springboot静态资源存放位置(4个位置):
- classpath(resources)下的META-INF下的resources
- classpath(resources)下的resources
- classpath(resources)下的static (最常用)
- classpath(resources)下的public
从上往下优先级依次降低,如果同时写这四个文件夹,并且文件名相同,访问的时候,会显示最上面一个文件夹内的内容
可以在主配置文件中修改静态资源的位置
spring:
resources:
static-locations:classpath:/静态资源存放的文件名/
默认首页:在静态资源的位置,建立一个index.html 就是默认首页
在resources文件夹下建立一个叫做 banner.txt 的文件,再次启动的时候,控制台的 sping 图案 会变成你banner.txt 中的内容。
如何在SpringBoot中使用servlet,Filter
写好servlet,filter之后,在主配置类上添加注解:@ServletComponentScan即可
servlet,filter都使用的是这个注解。
SpringBoot
使用Redis
查找起步依赖 导入。找对应的redisautoconfigretion