springboot

springboot

概述

简介:SpringBoot是基于Spring出现的一个快速搭建方便管理测试运行监控的工具框架,其设计目的是用来简化Spring应用的初始搭建以及开发过程,该框架使用了特定的方式来进行配置,即它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,SpringBoot整合了所有的框架。

spring boot只是一个辅助工具,配置工具,整合工具;

特点:

  • 独立运行的Spring容器
  • 内嵌servlet容器
  • 简化依赖
  • 自动配置

开始使用

  1. 创建一个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>
  1. 编写main方法
    main方法完成后,SpringBoot项目就可以正常启动了,同时可以直接开始编写Controller代码了。
@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class);
    }
}
  1. 启动项目
  • 在开发工具中直接运行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标签库不兼容;

使用:

  1. 引入依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
  1. 编写html文件,即thymeleaf文件,放在resources/templates/目录下;
  2. 到此,就可以在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/**");
    }
}

附:WebMvcConfigurerWebMvcConfigurationSupport的一个扩展类,它没有扩展新功能,只是为了让用户更加安全的添加自定义的配置,即使用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注解或者通过ServletRegistrationBeanBean来配置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注解配置RedisTemplateStringRedisTemplate
  • 附:此时的redis虽然可以使用,但是在应用启动后第一次使用redis时会很慢!

缓存

从spring3.1开始,引入了Cache支持,定义了org.springframework.cache.Cacheorg.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");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值