springboot
目录
概述
简介:SpringBoot是基于Spring出现的一个快速搭建方便管理测试运行监控的工具框架,其设计目的是用来简化Spring应用的初始搭建以及开发过程,该框架使用了特定的方式来进行配置,即它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,SpringBoot整合了所有的框架。
spring boot只是一个辅助工具,配置工具,整合工具;
特点:
- 独立运行的Spring容器
- 内嵌servlet容器
- 简化依赖
- 自动配置
开始使用
- 创建一个maven的quickstart项目,引入依赖
<!-- parent提供了dependencyManagement,可以忽略部分依赖的版本,也可以不继承该parent -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
- 编写main方法
main方法完成后,SpringBoot项目就可以正常启动了,同时可以直接开始编写Controller代码了。
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class);
}
}
- 启动项目
- 在开发工具中直接运行main方法;
- 在maven中添加以下插件后,就可以在项目根路径使用mvn spring-boot:run命令或者在mvn package打包后使用java -jar jar包名来启动项目。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
- 打成war包方式运行:
- 修改pom文件中的打包方式(jar改为war);
- spring-boot-starter-web中排除Tomcat依赖,或者scope改为provided;(经实践,该步骤可有可无);
- 启动类继承SpringBootServletInitializer并实现configure方法;
- 执行mvn package命令打成war包,这样就可以通过Tomcat运行了。
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Main.class);
}
核心注解
SpringBootApplication
是一个包括三个注解的复合注解;
- ComponentScan:扫描注解,默认扫描当前包及其子包下的注解标记到Spring容器;
- SpringBootConfiguration:继承自@Configuration,标注当前类是配置类,并将@Bean注解的方法纳入到Spring容器中;并可以读取两个配置文件;
- bootstrap.properties:配置中心的客户端springcloud组件;
- application.properties:全局配置文件,配置当前工程所有需要的内容,如:springmvc视图解析器的前后缀、DataSource参数等,可以代替SSM框架工程的所有
*.properties
文件;
- EnableAutoConfiguration:启用自动配置,即工程中如果有自定义的配置文件则使用自定义配置,如果没有则使用默认配置,如果也没有默认配置则抛出异常;
Banner
springboot启动时会打印banner文本,该文本可以通过在resources下添加banner.txt文件来自定义;
logger
springboot默认整合了LogBack日志,默认级别为info,日志默认打印到控制台,也可以用如下方式自定义;
# 全局日志级别,默认info
logging.level.root=info
# 自定义某个包的日志级别
logging.level.com.demo.springbootdemo.interceptor=debug
# 启用日志文件,并自定义日志文件路径与名称
# logging.file=./logs/test.log
# 日志格式
# logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
# 关闭控制台输出
# logging.pattern.console=
在类中使用日志:
private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MyFilter.class);
配置文件
application.properties
全局配置文件,实例:
server.port=80
server.context-path=/
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql:///test01?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=root
也可以使用application.yml格式的配置文件,使数据更清晰:(底层仍然会转为properties文件)
server:
port: 80
context-path: /
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql:///ms_demo?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username=root
password=root
额外的配置文件
当需要有额外的配置文件时(如:quartz定时器的配置文件),可以通过注解追加其他配置文件:
@ImportResource (value={“xml1”,“xml2”,“xml3”})
多环境配置文件
实际开发中,不同的环境中配置不同,可以添加按格式application-{profile}.yml命名的多个配置文件,其中{profile}对应环境标识,然后在application.yml文件添加:
spring:
profiles:
active: profile(环境标识)
启动时选择配置环境:java -jar ./target/xxx.jar.jar --spring.profiles.active=prod
springmvc
springboot整合springmvc只需要引入web依赖即可,但还不能使用jsp,thymeleaf等,只能返回json数据;
mvc常用的配置有:
# 配置静态资源访问,默认配置没有static前缀
spring.mvc.static-path-pattern=/static/**
# 静态资源路径,默认值为:"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"
spring.resources.static-locations=classpath:/static/
# 文件上传大小限制,默认1MB
spring.servlet.multipart.max-file-size=100MB
# 每次请求的最大值,默认10MB
spring.servlet.multipart.max-request-size=120MB
# post参数大小限制
spring.http.multipart.max-file-size=100Mb
spring.http.multipart.max-request-size=120Mb
经典面试题:springmvc执行流程:
- 请求匹配到前端控制器(DispatcherServlet)进行处理(其实就是web.xml中的一个servlet);
- 前端控制器将请求信息交给处理器映射器(HandlerMapping)处理;
- 处理器映射器返回一个执行链给前端控制器;
- 前端控制器调用处理器适配器(HandlerAdapter),同时将执行链传递给处理器适配器;
- 处理器适配器根据执行链调用处理器(Handler)处理请求,也就是给拦截器、controller处理;
- 处理器处理完成后返回ModelAndView给处理器适配器;
- 处理器适配器返回ModelAndView给前端控制器;
- 前端控制器请求视图解析器(ViewResolver)解析视图;
- 视图解析器解析完成并返回视图(View)对象给前端控制器;
- 前端控制器渲染视图并返回给用户。
thymeleaf
官方推荐!具有以下特点:
- 使用专用命名空间将静态页面转为动态页面;
- 使用@{}引用上下文路径;
- 使用spring表达式语言;
- 开源框架,每月更新,文档完善;
- 更适合设计页面;
- 表达式语言更强大;
但是也有以下缺点:
- 没有自定义标签;
- 与jsp标签库不兼容;
使用:
- 引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
- 编写html文件,即thymeleaf文件,放在resources/templates/目录下;
- 到此,就可以在controller中访问thymeleaf文件了。
附:
# 配置静态资源访问,默认配置没有static前缀
spring.mvc.static-path-pattern=/static/**
# 静态资源路径,默认值为:classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/
#spring.resources.static-locations=classpath:/static/
# 开发环境需关闭缓存,及时刷新,更多thymeleaf配置见ThymeleafProperties类
spring.thymeleaf.cache=false
全局异常处理
- 编写全局异常处理类,并添加类注解:
@ControllerAdvice
- 在全局异常处理类中编写异常处理方法:
/**
* 该注解也可以单独在Controller下使用,用作优先级更高的局部异常处理
* 注解中的Exception可以改为作用范围更小的异常类,单独处理某些异常
* 这个方法可以编写多个,这里Exception这个异常的优先级最低
* 这个其实也就是个controller方法
*/
@ExceptionHandler(Exception.class)
public String allException(Exception e, Model model) {
logger.error(e.getMessage(), e);
model.addAttribute("data", "出错了:" + e.getMessage() +
"\n" + e.getStackTrace()[0].toString());
return "index";
}
404处理
- 添加配置:
# 要在统一异常处理中处理404
spring.mvc.throw-exception-if-no-handler-found=true
# 关闭静态资源默认处理,配置这个会导致静态资源404
# spring.resources.add-mappings=false
- 在全局异常处理类中添加如下方法:
@ExceptionHandler(NoHandlerFoundException.class)
public String exception404(Exception e, Model model) {
logger.error(e.getMessage());
model.addAttribute("data", "出错了:" + e.getMessage() +
"\n" + e.getStackTrace()[0].toString());
return "404";
}
拦截器
- 编写类实现
HandlerInterceptor
接口,并实现相关方法;
@Component
public class MyInterceptor implements HandlerInterceptor {
private static Logger logger = LoggerFactory.getLogger(MyInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
logger.debug("\n拦截器执行了。访问地址:" + request.getRequestURL());
return true;
}
}
- 编写WebMvc配置类是实现
WebMvcConfigurer
或者WebMvcConfigurationSupport
接口
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private MyInterceptor myInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor)
.addPathPatterns("/**").order(1)
.excludePathPatterns("/static/**");
}
}
附:WebMvcConfigurer
是WebMvcConfigurationSupport
的一个扩展类,它没有扩展新功能,只是为了让用户更加安全的添加自定义的配置,即使用WebMvcConfigurer
,那么开发者是在默认配置的基础上添加自定义配置,而使用WebMvcConfigurationSupport
则可以重写默认配置,可能会使默认配置失效,进而导致相关功能无法使用。
文件上传
- 添加配置:
# 请求内容总大小,即上传文件总的最大值, 默认10MB
spring.servlet.multipart.max-request-size=10MB
# 单个文件的最大值,默认1MB
spring.servlet.multipart.max-file-size=1MB
- 编写对应controller
private String dir = "./files/";
@PostMapping("/upload")
public String upload(MultipartFile file1) throws IOException {
byte[] buffer = new byte[10240];
if (!file1.isEmpty()) {
File file = new File(dir + file1.getOriginalFilename());
if (file.exists()) {
logger.info("文件已存在");
return "redirect:/";
}
File dir = file.getParentFile();
if(!dir.exists()){
dir.mkdirs();
}
file.createNewFile();
// todo: 使用try,catch,finally
FileOutputStream out = new FileOutputStream(file);
InputStream in = file1.getInputStream();
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
in.close();
out.close();
}
return "redirect:/";
}
文件下载
- 编写方法:
@GetMapping("/down")
public void down(String name, HttpServletResponse res) throws IOException {
File file = new File(dir + name);
if(!file.exists()){
throw new IOException("文件不存在");
}
res.setHeader("Content-Type", MediaType.APPLICATION_OCTET_STREAM.toString());
res.setHeader("Content-Disposition", "attachment;filename=" +
URLEncoder.encode(file.getName(), StandardCharsets.UTF_8.toString()));
// todo: 使用try,catch,finally
ServletOutputStream out = res.getOutputStream();
FileInputStream in = new FileInputStream(file);
int len;
byte[] buffer = new byte[10240];
while((len = in.read(buffer)) > 0){
out.write(buffer, 0, len);
}
in.close();
out.close();
}
jsp
官方不推荐,理由如下:
- 代码冗长;
- 不符合HTML/css规范;
- 标签库没有更新,文档不健全;
使用jsp步骤如下:
- 引入jsp和jstl依赖:
<!--jsp-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!--c标签-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
- 添加配置
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
- 创建webapp/WEB-INF/views目录
- 完成,可以编写和使用jsp了。(但是这里只能通过在开发工具或者打成war包运行,其实有时候java -jar也可以运行war包,jar包方式访问页面会404,只有1.4.2的编译插件并指定资源目录的才不会404):
<!--要通过java -jar命令+jar包方式访问,还需要需要如下配置-->
<build>
<resources>
<resource>
<directory>src/main/webapp</directory>
<targetPath>META-INF/resources</targetPath>
<includes>
<include>**/**</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<targetPath>BOOT-INF/classes</targetPath>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.4.2.RELEASE</version>
</plugin>
</plugins>
</build>
监听器
这里以HttpSessionListener
为例;
- 编写监听器实现
HttpSessionListener
接口
@Component
// @WebListener
public class MyListener implements HttpSessionListener {
private static final Logger logger = LoggerFactory.getLogger(MyListener.class);
@Override
public void sessionCreated(HttpSessionEvent se) {
logger.debug("创建session");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
logger.debug("销毁session");
}
}
- 上面的监听器类中也可以加上
@WebListener
注解,加上该注解则不需要下面的步骤了; - 在springboot的配置类中配置监听器:
@Bean
public ServletListenerRegistrationBean<MyListener> listenerRegister(){
ServletListenerRegistrationBean<MyListener> listener = new ServletListenerRegistrationBean<>();
listener.setListener(myListener);
return listener;
}
过滤器
- 编写过滤器实现Filter接口
@Component
// 这里的地址匹配使用web.xml规范
// @WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
private static Logger logger = LoggerFactory.getLogger(MyFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
String url = req.getRequestURI();
AntPathMatcher antPathMatcher = new AntPathMatcher();
String excludeUrl = "/static/**";
if(antPathMatcher.match(excludeUrl, url)){
filterChain.doFilter(servletRequest, servletResponse);
return;
}
logger.debug("\n过滤器执行了······" + req.getRequestURL());
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
- 上面过滤器类上,也可以添加
@WebFilter
注解,加上该注解则不需要下面的步骤了; - 在springboot配置类中配置过滤器:
@Bean
public FilterRegistrationBean<MyFilter> filterRegister(){
FilterRegistrationBean<MyFilter> filter = new FilterRegistrationBean<>();
filter.setFilter(myFilter);
filter.setOrder(1);
// 这里的地址匹配使用web.xml规范
filter.addUrlPatterns("/*");
return filter;
}
servlet
与过滤器和监听器的方法类似;即:
- 编写servlet继承
HttpServlet
,实现相关方法; - 使用
@WebServlet
注解或者通过ServletRegistrationBean
Bean来配置servlet;
jpa
使用
- 引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
- 添加配置
# 配置数据源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
#验证连接是否有效。此参数必须设置为非空字符串,下面三项设置成true才能生效
spring.datasource.validationQuery=SELECT 1
#指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
spring.datasource.testWhileIdle=true
#指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
spring.datasource.testOnBorrow=true
#指明是否在归还到池中前进行检验
spring.datasource.testOnReturn=false
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=1800000
# 禁用视图
spring.jpa.open-in-view=false
# mybatis可以通过设置日志级别为debug打印sql,但是jpa不行
# 显示sql、格式化sql、sql参数
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=trace
- 接着就可以建表、建model、dao、service等类来使用jpa了;
druid
github文档:https://github.com/alibaba/druid/wiki/
使用
- 依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
- 添加配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin
spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.merge-sql=true
# 超过此时间即为慢sql,单位:毫秒
spring.datasource.druid.filter.stat.slow-sql-millis=10
- 访问:
http://localhost/druid
即可监控应用运行情况。
mybatis
开始
使用mybatis前,先把上面的jpa加的内容去掉;
使用步骤如下:
- 引入mysql驱动、mybatis-starter等依赖;
<!--整合mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
- 数据源、mybatis等配置(还可以配置mybatis配置文件路径,然后添加mybatis配置文件);
示例配置如下:
spring.datasource.url=jdbc:mysql:///test01?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 对应mapper映射xml文件的所在路径
mybatis.mapperLocations=classpath:mapper/*.xml
# 配置别名,对应实体类的路径
mybatis.typeAliasesPackage=com.example.pojo
- 在启动类中通过@MapperScan配置mapper接口路径(也可以在mapper接口中使用@Mapper)
- 整合基本完成,可以编写Mapper接口和对应的xml配置了。后面接着添加分页插件和通用mapper插件;
分页插件
- 依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
- application.yml添加分页插件配置;
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql
tkmapper
- 添加分页插件完成,接着添加通用mapper插件依赖:
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
- application.yml中添加通用mapper配置;
mapper.not-empty=false
mapper.identity=mysql
- 在启动类中添加@MapperScan注解配置mapper路径(注意使用tk包中的注解);
- 最后在编写Mapper接口时需要继承Mapper接口,即:
public interface AMapper extends Mapper<A>{}
- 整合完成,可以使用通用Mapper中封装好的单表查询方法了(若表、字段名与实体类的类名、字段不一致,可以通过jpa中的@Table、@Id、@Column、@Transient注解指定)。
缓存
一级缓存:
- 一级查询缓存也叫本地缓存,是基于PerpetualCache的HashMap本地缓存,其作用域为同一个sqlSession;
- 同一个作用域下两次相同查询,第二次不在查询数据库,而是直接从缓存获取;
- sqlSession结束后,一级缓存就没了;
- 一级缓存默认开启,且不能关闭;
- 增删改会清空缓存,无论是否commit;
- spring整合mybatis后的情况:
- 非事务环境每次操作都使用新的sqlSession,因此一级缓存无效;
- 事务环境下,一级缓存有效,两次相同查询会得到同一个对象;
二级缓存:
- 二级缓存的作用域是mapper范围的;
- sqlSession关闭后才会将数据写到二级缓存;
- 增删改操作无论是否提交,都会清空缓存;
- 二级缓存默认开启,使用LRU(最近最少使用)算法回收,默认同样使用HashMap存储;
- 缓存查询的对象是可读可写的,不会干扰其他的调用者;
- 二级缓存全局开启的情况下,给某个xml开启二级缓存只需要在该xml下添加
<cache/>
即可; - 如果想设置某个增删改操作不清空缓存的话,可以在标签中添加
flushCache="false"
- 另外,还可以在cache标签中配置收回策略、刷新间隔、引用数目、只读,也可以使用
@CacheNamespace
注解配置缓存属性; - 脏读:
- 产生:通常情况下,每个mapper都有自己的缓存,互不影响,但是在某些多表关联操作中,两个不同的mapper涉及到了同一个表,其中一个mapper查询后,另一个mapper进行了更新操作,然后第一个mapper再次查询时,得到的就是脏数据;
- 解决:1.mapper尽量以单表操作为主,2.使用参照缓存;
- 集成redis缓存:项目中整合好redis,并 引入集成依赖;
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-redis</artifactId>
<version>1.0.0-beta2</version>
</dependency>
- 在xml中配置
<cache type= "org.mybatis.caches.redis.RedisCache" />
- RedisCache 在保存缓存数据和获取缓存数据时,使用了Java的序列化和反序列化,因此还需要保证被缓存的对象必须实现
Serializable
接口,另外这样还可以实现分布式应用间的缓存共享。
swagger
官方文档:https://swagger.io/docs/
使用方法:
- 引入依赖
<!-- swagger依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- swagger中的数字需要添加example,否则会报错,但是不影响功能,但是下面的版本修复了这个bug -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
- 新增swagger配置类
@Configuration
@EnableSwagger2
public class SwaggerConfig {
private String name1 = "name1";
private String name2 = "name2";
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo()).select()
.apis(RequestHandlerSelectors.basePackage("com.demo.springbootdemo.controller"))
.paths(PathSelectors.any()).build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
}
/**
* 添加摘要信息
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("标题:XXX系统接口文档")
.description("描述:这都是些测试的接口")
.contact(new Contact("ls", null, null))
.version("1.0").build();
}
/**
* 下面两个方法用于添加自定义验证参数配置,即添加全局请求参数和请求头
*/
private List<SecurityScheme> securitySchemes() {
// 三个参数依次为:名称、参数名称、参数类型
return Arrays.asList(
new ApiKey(name1, "token1", "query"),
new ApiKey(name2, "token2", "header"));
}
private List<SecurityContext> securityContexts() {
AuthorizationScope[] authorizationScopes = {new AuthorizationScope("global", "accessEverything")};
List<SecurityReference> securityReferences = Arrays.asList(new SecurityReference(name1, authorizationScopes),
new SecurityReference(name2, authorizationScopes));
return Arrays.asList(SecurityContext.builder().securityReferences(securityReferences)
.forPaths(PathSelectors.any()).build());
}
}
- 在WebMvc配置类中添加如下配置:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
}
- 接下就可以在接口中使用swagger注解了,接口文档地址:
http://localhost/swagger-ui.html
redis
- 引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 添加配置:
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-wait=-1
spring.redis.jedis.pool.max-idle=500
spring.redis.jedis.pool.min-idle=0
spring.redis.lettuce.shutdown-timeout=0
- 在需要使用的类中使用
@Autowired
注解配置RedisTemplate
或StringRedisTemplate
- 附:此时的redis虽然可以使用,但是在应用启动后第一次使用redis时会很慢!
缓存
从spring3.1开始,引入了Cache支持,定义了org.springframework.cache.Cache
和 org.springframework.cache.CacheManager
等接口,通过实现这两个接口可以方便的管理不同的缓存技术;
spring cache使用方法和原理类似于spring对事物管理的支持,是作用在方法上,即,每次调用一个缓存方法时,会先检查指定参数的目标方法是否已经被调用过,如有,则直接返回结果,否则把该方法参数和返回值作为键值对存放在缓存中,然后再返回结果;
具体使用步骤如下:
- 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
- 启动类添加
@EnableCaching
注解; - 配置Bean:
CacheManager
; - 在需要缓存的方法上添加缓存注解即可;
缓存注解(可以在类或方法上):
@Cacheable
:标记为支持缓存(但是在对象内部调用不会触发缓存,原理类似事物);@CachePut
:类似@Cacheable
,不同之处在于每次都会执行方法,并将结果存入缓存;@CacheEvit
:标记为需要缓存清除操作;@Caching
:用于同时指定上面三个注解;
示例:
/**
* cacheNames为缓存名称,必须有,CACHE_NAME是字符串静态常量
* key是缓存数据的key,其值是spel表达式,同时提供了一个root对象,具体属性可以参考ide的代码提示
*/
@Cacheable(cacheNames = CACHE_NAME, key = "'str_' + #root.targetClass")
public String findXxx(String Xxx){
return "xxx";
}
测试
使用
- 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
- 编写测试类
package com.demo;
import com.demo.springbootdemo.SpringbootDemoApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
// 如果只是想要个普通的测试类,把这两个注解注释掉就可以了
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootDemoApplication.class)
public class MainTest {
@Test
public void test01(){
System.out.println("test01");
}
}