2021-09-23

springboot的使用

一、springboot简介

1.简介
SpringBoot是由Pivotal团队在2013年开始研发、2014年4月发布第一个版本的全新开源的轻量级框架。它基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。

2.特点
SpringBoot所具备的特征有:
(1)可以创建独立的Spring应用程序,并且基于其Maven或Gradle插件,可以创建可执行的JARs和WARs;
(2)内嵌Tomcat或Jetty等Servlet容器;
(3)提供自动配置的“starter”项目对象模型(POMS)以简化Maven配置;
(4)尽可能自动配置Spring容器;
(5)提供准备好的特性,如指标、健康检查和外部化配置;
(6)不需要XML配置。
注:Springboot不是对Spring的增强,而是对Spring的简化

3.重要策略
SpringBoot框架中还有两个非常重要的策略:开箱即用和约定优于配置。开箱即用,Outofbox,是指在开发过程中,通过在MAVEN项目的pom文件中添加相关依赖包,然后使用对应注解来代替繁琐的XML配置文件以管理对象的生命周期。这个特点使得开发人员摆脱了复杂的配置工作以及依赖的管理工作,更加专注于业务逻辑。约定优于配置,Convention over configuration,是一种由SpringBoot本身来配置目标结构,由开发者在结构中添加信息的软件设计范式。这一特点虽降低了部分灵活性,增加了BUG定位的复杂性,但减少了开发人员需要做出决定的数量,同时减少了大量的XML配置,并且可以将代码编译、测试和打包等工作自动化。
总结:
(1)Springboot对原Spring当中导入依赖做了整合,帮我们封装一些已经调试好的依赖(都是相互兼容)
(2)SpringBoot通过自动配置策略,帮我们省了很多原Spring当中需要配置的东西
(3)每个springboot的web程序都自动内置了tomcat插件,给微服务的开发提供了方便
(4)SpringBoot对目录结构有一些特殊的要求(约定),从而节省了一些配置

4.springboot与springmvc、spring、springcloud关系
springmvc: DispatcherServlet ModelAndView 等开发Controller,web应用程序
spring: ioc和aop
springboot:提供快速开发spring应用程序一种方式,基于spring(ioc和aop),既可以替代传统的 ssm框架,又是微服务springcloud开发的基础
springcloud:微服务全套解决方案,基于springboot进行开发
配置中心:spring config 或者apollo
网关(路由):api gateway或者zuul
服务注册与发现: eureka或者zookeeper
熔断器(熔断、降级、限流):hystrix
负载均衡:Ribbon
RPC客户端:feign客户端
服务监控:actuator
安全:security

二、springboot的搭建
1.准备工作
jdk1.8
maven3.3
idea
2.springboot开发工具
myeclipse
eclipse+sts spring tool suite 插件
sts开发工具
idea(推荐)
3.开发一个简单的springboot程序
(1)通过官方网站的

(2)创建一个maven工程(手动)
a.版本管理中心(定义了所有可能会用到的依赖的版本)
–主要做版本的管理(版本的仲裁中心)

spring-boot-parent
org.springframework.boot
2.1.3.RELEASE

b.场景启动器(开发哪类程序需要导入的依赖的统一管理)

org.springframework.boot
spring-boot-starter-web

c.创建一个springboot启动程序

启动类
package org.lanqiao;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//springboot应用程序启动需要的注解
@SpringBootApplication
public class App {
public static void main(String[] args) {
//springboot应用程序启动执行
SpringApplication.run(App.class,args);
}
}

controller:
package org.lanqiao.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {
@GetMapping("/hello")
@ResponseBody
public String hello(){
return “springboot的第一程序”;
}
}

(3)使用idea自带的spring intilizer创建springboot(等同于官网创建),需要联网,从官方网站下载

官网连接不稳定,可以尝试使用https://start.aliyun.com

4.springboot应用程序的构成
(1)POM.XML
a、引入父工程(在父工程中导入所有可能需要依赖的包的版本–版本控制中心)

org.springframework.boot
spring-boot-starter-parent
2.3.4.RELEASE

b、导入的依赖(可以不加版本,原因:父工程已经指定版本)
starter–场景启动器,提供了该场景所需要的所有的jar包依赖
场景启动器中不存在的依赖包—如jdbc驱动包
c、springboot所内嵌的maven插件

org.springframework.boot spring-boot-starter-jdbc com.zaxxer HikariCP (2)主应用程序 @SpringBootApplication public class MybootApplication { public static void main(String[] args) { SpringApplication.run(MybootApplication.class, args); } }

三、springboot程序及注解原理
springboot应用程序
— 自己写的程序代码(一定要在主程序所在包下或其子包下才可以被扫描到)
— 第三方的jar包的程序 springmvc jackon等和配置
@SpringBootApplication

  • @SpringBootConfiguration
    - @Configuration //声明当前的类是一个配置类
  • @EnableAutoConfiguration //启用自动配置
    - @AutoConfigurationPackage //把主类所在包下的所有类加载到spring ioc容器中
    - @Import({Registrar.class})
    AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
    //得到的值就是org.lanqiao就是主启动类所在的包,会自动扫描该包及子包下的所有程序注入到ioc容器中
    - @Import({AutoConfigurationImportSelector.class})

自动导入第三方包和配置
@Import({AutoConfigurationImportSelector.class})
–public String[] selectImports(AnnotationMetadata annotationMetadata)
–this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
//springboot可以加载的所有的自动配置类,这些帮我们都自动配置,省掉了我们自己需要配置的xml文件等

这些配置类从哪里来的?
List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
List configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());

loadFactoryNames(EnableAutoConfiguration.class, this.getBeanClassLoader());

举例:不排除的自动配置类

举例:被加载的自动配置类

@SpringBootApplication(exclude = JdbcTemplateAutoConfiguration.class)
Exclusions:

org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration

run方法:
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
ConfigurableApplicationContext ac = SpringApplication.run(MyApp.class);
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
System.out.println(beanDefinitionNames.length);
}
}
四、Springboot配置文件及yaml
绝大多数情况都是自动配置完成的,很多时候可以不需要自己配置,有时需要定制化的配置,要使用配置文件
SpringCloud或Dubbo等都需要进行配置
1.配置文件有哪些: 越常用的优先级越低(方便被临时覆盖)
默认的配置文件(可以用哪些,放在哪,内容怎么写)
(1)支持文件类型properties yml(yaml) xml
application.properties application.yml application.yaml
application.properties的优先级大于application.yml
(2)放在哪?可以放在4个位置
src/main/resources 优先级最低
src/main/resources/config 优先级第三
应用程序下 优先级第二
应用程序/config 优先级最高
(3)配置文件的内容
正常情况下,可以不需要该配置文件仍然可以使用springboot,因为springboot自动配置,会有一些基本的默认的配置可以保证程序正常的使用,可以在配置文件中使用debug=true查看加载的自动配置类

如何修改自动配置中的默认配置
要修改哪个配置,找到对应的自动配置类XxxxxxAutoConfiguration—XxxxProperties(自动配置类会读取的默认属性)
XxxxProperties------@ConfigurationProperties(
prefix = “spring.mvc”
)//该配置对应前缀,要修改该配置,可以在application.properties —>设置spring.mvc.XXXX
自定义配置文件(默认配置中主要是用来重写自动配置的内容,自定义配置文件主要放你额外需要的信息)
(1)自定义的属性文件
my.properties name=张三
@PropertySource:加载指定的配置文件,只能加载properties,不支持yaml
(2)原spring配置文件
spring.xml
@ImportResource(location={“classpath:spring.xml”})
@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效(不建议使用)
自定义配置类(建议)
@Configuration
public class AppConfig{
@Bean(“userService”)
public UserService userService(){
return new UserService();
}
}

2.yaml入门
(1)yaml YAML Ain’t a Markup Language 以数据为中心数据序列化文件
yaml:
server:
port: 9999
servlet:
context-path: “/aaa”
spring:
mvc: aaa
path: bbb

xml:

9999

“/aaa”

properties
server.port=8081
server.path=/
spring.mvc=aaa
spring.path=bbb

(2)yaml基本语法
key:空格value
垂直对齐的方式表示层次结构
下一个层级需要使用空格,但可以不限制空格的个数
#表示注释
一般的字面量的值不需要加什么特殊符号,比如字符串、整数、布尔型等值都不需要加符号
字符串可以加单引号或者双引号,主要区别在一些转移字符上
server:
port: 9999 #server.port=9999
path: /
aaa: bbb #server.path.aaa=bbb

yaml数据类型
student:
name: 张三
age: 21
isBoy: false
birth: 1998/12/12
hobby: #[足球,篮球] //List String[]
- 篮球
- 足球
course:#{name: 英语,teacher: 李四}
name: 英语
teacher: 李四

yaml数据类型:
简单类型可以直接使用字面量字符串、数字、boolean和日期
复杂类型:
数组/set/list :
hobby:
- 篮球
- 足球

inline行内写法(方括号可以省略)
hobby: [篮球,足球]
hobby: 篮球,足球

 Map或者对象

course:
name: 英语
teacher: 李四

inline行内写法(大括号不可以省略)

course: {name: 英语,teacher: 李四}

对应的属性文件
student.name=张三
student.age=21
student.isBoy=false
student.birth=1998/12/12
student.hobby=篮球,足球
student.course.name=英语
student.course.teacher=李四

(3)读取yaml自定义配置的信息
@ConfigurationProperties可以把配置文件中的信息注入到该类中的属性(配置信息要与属性名一致)
@Data
@ToString
@Component
@ConfigurationProperties(“student”)
public class Student {
private String name;
private Integer age;
private Boolean isBoy;
private Date birth;
private List hobby;
private Course course;
}

@Value
public class Student {
@Value(" s t u d e n t . n a m e " ) p r i v a t e S t r i n g n a m e ; p r i v a t e I n t e g e r a g e ; p r i v a t e B o o l e a n i s B o y ; p r i v a t e D a t e b i r t h ; p r i v a t e L i s t < S t r i n g > h o b b y ; @ V a l u e ( " {student.name}") private String name; private Integer age; private Boolean isBoy; private Date birth; private List<String> hobby; @Value(" student.name")privateStringname;privateIntegerage;privateBooleanisBoy;privateDatebirth;privateList<String>hobby;@Value("{student.course}")
private Course course;
}

Feature@ConfigurationProperties@ValueRelaxed binding松散绑定YesNoMeta-data support 复杂数据(集合和对象)YesNoSpEL evaluationNoYesjsr303校验Yes @Validated @EmailNo 处理方式批量注入单值注入什么时候使用类似自动配置类,自定义配置类,可以把某些属性值放在配置文件中,使用配置类自动读取这些值一般都是自定义某些可能会经常变化的值

松散绑定:
acme.my-project.person.first-nameKebab case, which is recommended for use in .properties and .yml files.acme.myProject.person.firstNameStandard camel case syntax.acme.my_project.person.first_nameUnderscore notation, which is an alternative format for use in .properties and .yml files.ACME_MYPROJECT_PERSON_FIRSTNAMEUpper case format, which is recommended when using system environment variables.
jsr303校验
package org.lanqiao.entity;

import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
@Component
@Data
@ConfigurationProperties(prefix = “student”)
@Validated//使用jsr303校验
public class Student {
private Integer id;
//@Value("${first-name}")
@NotNull
@Length(min=3,max=6)
private String firstName;

private Boolean isBoy;
private String birth;
//@Email
private String email;
private List<String> hobby;
private Map<String,Object> map;
//@Value("${student.course}")
private Course course;

}

属性文件乱码问题

3.Profiles环境配置文件
(1) 开发场景: application-环境名.properties
开发环境dev
测试环境test
生产环境product
(2)切换环境的几种方式:
使用属性文件
application.properties
spring.profiles.active=dev //激活application-dev.properties文件的配置
application-dev.properties
application-test.properties
使用yaml

server:
port: 8080
spring:
profiles:
active: test
—//多文件分隔符,加上三个横杠就等价于下边是另外一个文档
server:
port: 7777
spring:
profiles: dev


server:
port: 8888
spring:
profiles: test

3.动态转换环境

五、springboot日志管理
1.日志:
log4j jcl(jakata common-logging) jul(java.util.logging) log4j2 logback slf4j
spring使用jcl
日志门面(接口规范) 日志实现
jcl slf4j log4j log4j2 logback jul

2.springboot使用日志
   第一种用法使用slf4j中的LoggerFactory.getLogger()获取logger
   logger.trace()..............

第二种方式使用注解(必须导入lombok)
@slf4j可以省略创建logger的代码

package org.lanqiao.controller;
@RestController
@Slf4j
public class MyController {
@Autowired
HelloService helloService;
@GetMapping("/hello")
public String hello(){
log.debug(“controller test debug”);
log.info(" controller test info");
log.error(“controller test error”);
helloService.hello();
return “hello”;
}
}

package org.lanqiao.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.lanqiao.service.HelloService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class HelloServiceImpl implements HelloService {
//Logger logger = LoggerFactory.getLogger(HelloServiceImpl.class);
@Override
public void hello() {
log.debug(“service test debug”);
log.info(" service test info");
log.error(“service test error”);
}
}

server:
port: 8082

logging:
level:
org:
lanqiao:
service: debug #控制service日志输出级别是debug
controller: info #控制controller日志输出级别是info
file:
path: e:/log #会在该目录下默认生成一个日志文件spring.log
name: e:/log/mylog.log # 可指定生成日志的名称和位置,优先级比path高,name和path同时存在只有name会生效

2021-09-22 18:22:58.180 INFO 5872 — [nio-8082-exec-1] org.lanqiao.controller.MyController : controller test info
2021-09-22 18:22:58.180 ERROR 5872 — [nio-8082-exec-1] org.lanqiao.controller.MyController : controller test error
2021-09-22 18:22:58.180 DEBUG 5872 — [nio-8082-exec-1] o.lanqiao.service.impl.HelloServiceImpl : service test debug
2021-09-22 18:22:58.180 INFO 5872 — [nio-8082-exec-1] o.lanqiao.service.impl.HelloServiceImpl : service test info
2021-09-22 18:22:58.180 ERROR 5872 — [nio-8082-exec-1] o.lanqiao.service.impl.HelloServiceImpl : service test error
六、springboot静态资源处理
js、html、css、图片、音频、视频这些静态资源

webjars

静态资源可以存放的位置(自动配置类默认设置的路径)
WebMvcAutoConfiguration进行对静态处理 webjars以及静态资源的路径

CLASSPATH_RESOURCE_LOCATIONS = new String[]{
“classpath:/META-INF/resources/”, “classpath:/resources/”, “classpath:/static/”, “classpath:/public/”};

可以把静态资源放入这4个路径下,访问时无需带这些文件夹的名字

七、springboot整合模板文件thymeleaf
thymeleaf freemark都是模板引擎(把数据填充生成一个静态页面)
springboot默认是不支持jsp,因为springboot默认使用内嵌tomcat
springboot建议使用静态模板引擎thymeleaf,thymeleaf就是一个html页面

使用thymeleaf模板引擎主要来实现前后端分离

jsp+ssm部署在一起
thymeleaf+vue.js 放在一个项目里 (主要通过restful等获取数据填充到页面中)

ssm放在一个项目(不要需要有前台页面,主要提供服务)

使用thymeleaf过程:
第一步、导入thymeleaf的依赖

第二步、创建controller提供数据

package org.lanqiao.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {
@GetMapping("/hello")
public String sayHello(Model model){
model.addAttribute(“name”,“张三”);
return “hello”;
}
}

第三步、创建html页面

第四步、启动springboot,使用localhost:8080/hello访问

八、springboot整合mybatis
整合持久层框架
-mybatis
-mybatis-plus
-jpa(基于hibernate)
1.docker的安装使用及在docker内安装mysql
(1) 安装的docker
yum -y install docker

(2)查看docker版本

docker -v
Docker version 1.13.1, build 7f2769b/1.13.1

(3)启动docker

systemctl start docker

(4)查看docker的镜像

docker images

(5)搜索镜像

docker search mysql

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io

(6)下载镜像
修改下载镜像的服务器地址 /etc/docker/daemaon.json
docker pull mysql:5.7
docker pull mysql //默认下载lasted最新的版本
docker pull hub.c.163.com/library/mysql:5.7

(7)运行镜像(创建一个容器container)docker run
docker run -d --name mysql5.7 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123 mysql:5.7

docker run -d --name mysql5.7 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123 hub.c.163.com/library/mysql:5.7

这样可以使用mysql数据库
(8)查看docker进程
docker ps -a
(9)删除docker进程
docker rm 进程id
(10)重启docker服务
systemctl restart docker
注:云服务器可能会导致启动镜像失败,可以使用yum update更新yum依赖,重启docker即可

可以进入docker内部 mysql的命令在/usr/bin下

假如外部的客户端无法连接到docker
ALTER USER ‘root’@’%’ IDENTIFIED WITH mysql_native_password BY ‘newpassword’;

2.使用springboot整合mybatis(替代ssm)

第一步、创建工程

创建数据库连接
application.yml(配置连接数据库的基本信息)
spring:
datasource:
username: root
password: 123
url: jdbc:mysql://10.245.0.148:3306/mybatis
driver-class-name: com.mysql.jdbc.Driver

springboot默认使用数据源hikariCP

性能表现:hikariCP>druid>tomcat-jdbc>dbcp>c3p0

替换成druid的数据连接池
导入druid的依赖

com.alibaba druid 1.1.17

mapper接口(注:需要在接口上添加@Mapper)
package org.lanqiao.dao;

import org.apache.ibatis.annotations.*;
import org.lanqiao.entity.Student;

import java.util.List;

@Mapper
public interface StudentMapper {
@Select(“select * from student”)
public List getAllStudents();
@Select(“select * from student where id=#{id}”)
public Student getStudentById(Integer id);
@Insert(“insert into student(name,age) values(#{name},#{age})”)
public int insertStudent(Student student);
@Delete(“delete from student where id=#{id}”)
public int deleteStudent(Integer id);
@Update(“update student set name=#{name},age=#{age} where id=#{id}”)
public int updateStudent(Student student);
}

service
package org.lanqiao.service.impl;

import org.lanqiao.dao.StudentMapper;
import org.lanqiao.entity.Student;
import org.lanqiao.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
@Service(“studentService”)
public class StudentServiceImpl implements StudentService {
@Autowired
StudentMapper studentMapper;
@Override
public List getAllStudents() {
return studentMapper.getAllStudents();
}

@Override
public Student getStudentById(Integer id) {
    return studentMapper.getStudentById(id);
}

@Override
public int insertStudent(Student student) {
    return studentMapper.insertStudent(student);
}

@Override
public int deleteStudent(Integer id) {
    return studentMapper.deleteStudent(id);
}

@Override
public int updateStudent(Student student) {
    return studentMapper.updateStudent(student);
}

}

controller
package org.lanqiao.controller;

import org.lanqiao.entity.Student;
import org.lanqiao.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class StudentController {
@Autowired
StudentService studentService;
@GetMapping("/")
public List getAll(){
return studentService.getAllStudents();
}
@GetMapping("/{id}")
public Student getOne(@PathVariable(“id”) Integer id){
return studentService.getStudentById(id);
}
@PostMapping("/")
public int insert(Student student){
return studentService.insertStudent(student);
}
@DeleteMapping("/{id}")
public int delete(Integer id){
return studentService.deleteStudent(id);
}
@PutMapping("/")
public int update(Student student){
return studentService.updateStudent(student);
}

}

在restful中,get请求----查询
post请求-------添加
delete请求-----删除
put请求-----修改

druid # 配置获取连接等待超时的时间 # 下面为连接池的补充设置,应用到上面所有数据源中 # 初始化大小,最小,最大 initialSize: 1 minIdle: 3 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 30000 validationQuery: select 'x' testWhileIdle: true testOnBorrow: false testOnReturn: false # 打开PSCache,并且指定每个连接上PSCache的大小 poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 filters: stat,wall,slf4j # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 合并多个DruidDataSource的监控数据 useGlobalDataSourceStat: true

@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), “/druid/*”);
// IP白名单
servletRegistrationBean.addInitParameter(“allow”, “192.168.2.25,127.0.0.1”);
// IP黑名单(共同存在时,deny优先于allow)
servletRegistrationBean.addInitParameter(“deny”, “192.168.1.100”);
//控制台管理用户
servletRegistrationBean.addInitParameter(“loginUsername”, “admin”);
servletRegistrationBean.addInitParameter(“loginPassword”, “9527”);
//是否能够重置数据 禁用HTML页面上的“Reset All”功能
servletRegistrationBean.addInitParameter(“resetEnable”, “false”);
return servletRegistrationBean;
}

@Bean
public FilterRegistrationBean filterRegistrationBean() {
    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
    filterRegistrationBean.addUrlPatterns("/*");
    filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
    return filterRegistrationBean;
}

九、springboot整合swagger2
swagger2优点:自动生成接口文档
缺点:对代码侵入太大

接口interface
指的是给前端或者其他后端程序员调用的内容
生成文档主要就是controller层

1.导入依赖

<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
io.springfox springfox-swagger2 2.9.2

2.编写一个配置类
package org.lanqiao.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.ApiSelector;
import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.nio.channels.spi.SelectorProvider;
import java.util.concurrent.ConcurrentHashMap;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket(Environment environment){
//定义了一个dev环境
Profiles profiles = Profiles.of(“dev”);
//判断当前环境是否是dev环境flag=true代表当前就是dev环境(启用swagger),flag=flase不是dev环境(关闭swagger)
boolean flag = environment.acceptsProfiles(profiles);
//使用的是链式编程
return new Docket(DocumentationType.SWAGGER_2)
//组织名
.groupName(“后端开发1组”)
//文档的基本信息
.apiInfo(apiInfo())
//是否启用swagger
.enable(flag)
//转化设置
.select()
//要扫描的基础包
.apis(RequestHandlerSelectors.basePackage(“org.lanqiao.controller”))
//过滤路径
.paths(PathSelectors.any())
.build();
}

private ApiInfo apiInfo(){
    return new ApiInfoBuilder()
            .contact(new Contact("张三","","zhangsan@qq.com"))
            .description("学生管理系统api集合")
            .title("学生信息系统")
            .version("v1.2")
            .build();
}

}

4.controller上加入注解(与配置文件中的扫描路径一致)
package org.lanqiao.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.lanqiao.entity.Student;
import org.lanqiao.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Api(tags = “学生管理操作列表”)
@RestController
@RequestMapping("/student")
public class StudentController {
@Autowired
StudentService studentService;
@GetMapping("/")
public List getAll(){
return studentService.getAllStudents();
}
@GetMapping("/{id}")
@ApiOperation(value=“查询学生”,notes = “根据学生id查询学生信息”)
public Student getOne(@ApiParam(value = “学生id”,required = true) @PathVariable(“id”) Integer id){
return studentService.getStudentById(id);
}
@PostMapping("/")
public int insert(Student student){
return studentService.insertStudent(student);
}
@DeleteMapping("/{id}")
public int delete(Integer id){
return studentService.deleteStudent(id);
}
@PutMapping("/")
public int update(Student student){
return studentService.updateStudent(student);
}

}

5.实体类注解
package org.lanqiao.entity;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@ApiModel(value = “Student”,description = “学生实体类”)
public class Student implements Serializable {
@ApiModelProperty(“学生id”)
private Integer id;
@ApiModelProperty(“学生姓名”)
private String name;
@ApiModelProperty(“学生年龄”)
private Integer age;
}

6.效果展示

@Api:修饰整个类,描述Controller的作用
@ApiOperation:描述一个类的一个方法,或者说一个接口
@ApiParam:单个参数描述
@ApiModel:用对象来接收参数
@ApiModelProperty:用对象接收参数时,描述对象的一个字段
@ApiResponse:HTTP响应其中1个描述
@ApiResponses:HTTP响应整体描述
@ApiIgnore:使用该注解忽略这个API
@ApiError :发生错误返回的信息
@ApiImplicitParam:一个请求参数
@ApiImplicitParams:多个请求参数

在实际使用中,开发环境可以暴露swagger接口文档,在生产环境中不能暴露
通过以下可以设置
//定义了一个dev环境
Profiles profiles = Profiles.of(“dev”);
//判断当前环境是否是dev环境flag=true代表当前就是dev环境(启用swagger),flag=flase不是dev环境(关闭swagger)
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2)
//组织名
.groupName(“后端开发1组”)
//文档的基本信息
.apiInfo(apiInfo())
//是否启用swagger
.enable(flag)

japidocs
十、springboot整合redis
一 JSR107(下面会有具体Springboot代码演示)
Java Caching定义了5个核心接口,分别是CachingProvider, CacheManager, Cache, Entry 和 Expiry。
1 CachingProvider定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可以在运行期访问多个CachingProvider。

2 CacheManager定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。

3 Cache是一个类似Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个CacheManager所拥有。
4 Entry是一个存储在Cache中的key-value对.

5 Expiry 每一个存储在Cache中的条目有一个定义的有效期。一旦超过这个时间,条目为过期的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。

如下图所示:

HashMap cache = newHashMap();
cache.put(k,v);
二 Spring缓存抽象(下面会有具体Springboot代码演示)
Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术;并支持使用JCache(JSR-107)注解简化我们开发;
1 Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;

2 Cache接口下Spring提供了各种xxxCache的实现,如RedisCache,EhCacheCache , ConcurrentMapCache等;每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果返回给用户。下次直接从缓存中获取。

3 使用Spring缓存抽象时我们需要关注以下两点;

第一点就是确定方法需要被缓存以及他们的缓存策略 ,第二点就是从缓存中读取之前缓存存储的数据,如下图所示:

了解jdbc的朋友就会很清楚,这就跟面向jdbc编程是一个道理,统一一个规范,统一面向jdbc编程。

三 缓存注解(下面会有具体Springboot代码演示)

@CacheConfig(cacheName=“student”)让当前类中所有的缓存存入该cacheName为student

@Cacheable(value=“student”,key=“key1”)

同样支持spel表达式

4.使用redis作为缓存机制的用法
(1)使用docker安装redis
docker pull redis

docker run -d --name redis -p6379:6379 redis

(2)导入依赖

org.springframework.boot
spring-boot-starter-data-redis

(3)设置redis 服务器地址:application.yml
spring:
redis:
host: 10.245.0.148 #redis的服务器地址

(4)在启动主类上加一个注解
@EnableCaching//告诉springboot启动缓存机制

第一种访问方式,使用RedisTemplate与StringRedisTemplate
package org.lanqiao;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.lanqiao.dao.StudentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import javax.sql.DataSource;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootMybatisApplicationTests {
@Autowired
DataSource dataSource;
@Autowired
StudentMapper studentMapper;

@Autowired
RedisTemplate redisTemplate; //<String,Object>
@Autowired
StringRedisTemplate stringRedisTemplate;//这个主要操作<String,String>

@Test
public void contextLoads() {
    String name = stringRedisTemplate.opsForValue().get("name");
    System.out.println(name);
    stringRedisTemplate.opsForValue().set("age","21");
    redisTemplate.opsForValue().get("age");

}

}

要把缓存的对象进行序列化

测试:
第一次访问

第二次访问:

没有再去数据库,但访问到结果,该结果表明是从缓存中取到的

注:redis默认使用的序列号策略是jdbc序列化方式,可以把它改成json格式序列化方式,方便读取

@cacheable与@cacheput区别
@cacheable 主要用在查询中,先到缓存服务器中查询cachename(Student)下的key(student::2)
找到对应value,一种找到了直接返回(不会再执行该方法),还有一种就是在缓存中没有找到,这时进入方法继续执行(访问数据库返回数据),再写入到缓存中

@cacheput 主要在修改中 首先就会继续执行该方法(直接访问数据库),把修改后的返回结果再加入到缓存中去

默认的keygenerator(key的生成器):把第一个参数的值作为key----student::2 cacheName::第一个参数的值

十一、其他内容
MQ,elasticsearch,springcloud体系,监控体系actuator,dubbo+zookeeper体系

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值