0
点赞
收藏
分享

微信扫一扫

Spring Boot 应用开发基本模板

本文主要介绍 Spring Boot 开发过程使用到的一些组件,帮助开发人员快速搭建基础开发框架。

1. 配置日志相关

1.1 日志级别 Level

日志的行为等级分为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL

Log4j 建议只使用四个级别,优先级从高到低依次是:ERROR、WARN、INFO、DEBUG。

1.2 配置示例

1. 配置 application.yml,指定 logback.xml 的详细地址。

logging:
  config: classpath:logback-config.xml

2. 配置 logback-config.xml,在配置文件中指定日志的打印级别,日志文件的存储路径等日志相关信息。

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds"
    debug="false">
    <property name="log.path" value="/project/logs/" />
    <!--输出到控制台 -->
    <appender name="console"
        class="ch.qos.logback.core.ConsoleAppender">
        <!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> 
            </filter> -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--输出到文件 -->
    <appender name="file"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}${log.file}</file>
<!--         <rollingPolicy -->
<!--             class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> -->
<!--             <fileNamePattern>${log.path}deepev.%d{yyyy-MM-dd_HH-mm}.log -->
<!--             </fileNamePattern> -->
<!--             <maxHistory>30</maxHistory> -->
<!--             <totalSizeCap>1GB</totalSizeCap> -->
<!--         </rollingPolicy> -->

        <!-- 滚动策略 日期+大小 策略 -->
        <rollingPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${log.path}deepev.%d{yyyy-MM-dd}.log-%i.zip</fileNamePattern>
            <!-- 单个日志大小 -->
            <maxFileSize>30MB</maxFileSize>
            <!-- 日志保存周期 -->
            <maxHistory>30</maxHistory>
            <!-- 总大小 -->
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>

        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="warn">
        <appender-ref ref="console" />
        <appender-ref ref="file" />
    </root>
    <!-- 指定业务包-->
    <logger name="com.**" level="INFO" additivity="false">
        <appender-ref ref="console" />
        <appender-ref ref="file" />
    </logger>

</configuration>

1.3 配置示例详解

根据上边的 logback-config.xml 文件,对 Logback 的相关配置进行详细讲解。

1. 根节点<configuration> 有三个属性,scan、scanPeriod 和 debug。

  • scan 值为 true 或 false,用于监控配置文件,如果文件发生改变后,将会被重新加载,此属性默认为 true。
  • scanPeriod 是时间间隔,是用来设置监测配置文件是否有修改,默认的时间单位是毫秒,只有 scan 设置为 true 时,此属性才会生效。
  • debug 此属性值为 true 或者 false,用于控制是否打印出 Logback 内部日志信息,设置为 true 时,可以通过 Logback 的内部日志,实时查看 Logback 运行状态。默认值为 false。

2. <appender> 节点是负责写日志的组件,有两个必须的属性,分别是 name 和 class,name 用于指定 appender 组件的名称,class 是 appender 组件的策略。

这里介绍一下 appender 的常用的组件:

  • ConsoleAppender 控制台组件,该组件是把日志输出到控制台上。上边示例中的 name=“console” 的组件就是这种策略。console 组件中的 <encoder> 部分是用来格式化日志格式的。
  • FileAppender 文件组件,该组件是把日志输出到文档中去。
    • <file>info.log</file>:指定日志被写入的文件的地址,该地址可以是相对目录,也可以是绝对目录。指定的目录如果不存在的话,会自动创建。
    • <append>true</append>:文件的写入类型,true 的话新生成的日志会追加到文件的结尾,如果为 false,则清空现有的文件。默认值为 true。
  • RollingFileAppender 滚动记录文件组件,该组件与 FileAppender 相比,增加了 rollingPolicy 属性,是对日志滚动处理时,指定对文件复制和重命名时的滚动的策略。

常用策略有三种:

  • ch.qos.logback.core.rolling.TimeBasedRollingPolicy:根据时间来制定滚动策略。
  • ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy:查看当前日志文件的大小,当超过指定大小时,会告知 RollingFileAppender,触发当前日志文件滚动。
  • ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy: 根据日期和大小同时确定滚动策略。

3. <logger> 节点:用来设置某一个包或具体的某一个类的日志打印级别、以及指定<appender>。在 logger 节点下可以包含零个或多个<appender-ref> 元素,ref 值用于标识 appender 的 name,并添加到这个 logger 中。上面的示例中,添加了两个 appender-ref,分别指定 file。

4. <root>节点,它是根 logger,是所有 logger 的上级,只有一个 level 的属性,用于指定日志等级。

2. 集成 Swagger,生成接口文档

Swagger 2

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。

2.1 添加依赖

这里我添加了两个 UI,springfox-swagger-ui 是官方提供的,swagger-bootstrap-ui 是第三方封装的,我平时更习惯使用第三方 UI。

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>swagger-bootstrap-ui</artifactId>
    <version>1.9.1</version>
</dependency>

2.2 application.yml 中添加开关

Swagger 只能在开发环境使用,部署生产环境时要关闭,为了方便管理,在配置文件中添加开关。

swagger:
  enable: true

2.3 编写 Swagger 配置类

在该配置类中,可以配置 API 文档中的显示信息,通过全局配置,可以为所有的 API 接口添加通用条件。

下面的示例中为所有的接口添加 token 公共配置的方法。

package com.**.**.conf;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Value("${swagger.enable}")
    private boolean enableSwagger;

    @Bean
    public Docket docket(){
        List<Parameter> params = getParam();
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).enable(enableSwagger).select()
                //当前包路径
                .apis(RequestHandlerSelectors.basePackage("com.reach.usercenter"))
                .paths(PathSelectors.any())
                .build()
//                .securitySchemes(security()).securityContexts(securityContexts()); //添加全局 token
                .globalOperationParameters(params);//在每一个接口上添加 token
    }

    private List<Parameter> getParam(){
        ParameterBuilder ticketPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<Parameter>();
        ticketPar.name("Authorization").description("user ticket")//Token 以及 Authorization 为自定义的参数,session 保存的名字是哪个就可以写成那个
                .modelRef(new ModelRef("string")).parameterType("header")
                .required(true).build(); //header 中的 ticket 参数非必填,传空也可以
        pars.add(ticketPar.build());    //根据每个方法名也知道当前方法在设置什么参数
        return pars;
    }

    private List<SecurityContext> securityContexts() {
        List<SecurityContext> securityContexts=new ArrayList<>();
        securityContexts.add(
                SecurityContext.builder()
                        .securityReferences(defaultAuth())
                        .forPaths(PathSelectors.regex("^(?!auth).*$"))
                        .build());
        return securityContexts;
    }
    private List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        List<SecurityReference> securityReferences=new ArrayList<>();
        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
        return securityReferences;
    }

    private List<ApiKey> security() {
        ApiKey key = new ApiKey("Authorization", "Authorization ", "header");
        List<ApiKey> list = new ArrayList();
        list.add(key);
        return list;
    }

    //构建 api 文档的详细信息函数
    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("EV DATA RESTful API")
                .version("1.0")
                .description("API 描述")
                .build();
    }
}

3. 配置文件敏感信息加密

在开发的服务中,为了安全考虑,有一些信息是必须要进行加密处理的,比如数据库的密码等信息,开发环境和测试环境还好说,但是生产环境必须要保证信息安全。Jasypt 是一个通用的加密库,我们可以使用 Jasypt 对配置文件中的敏感信息进行加密处理。

3.1 添加依赖

<!-- https://mvnrepository.com/artifact/com.github.ulisesbocchio/jasypt-spring-boot-starter -->
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.2</version>
</dependency>

3.2 application.yml 配置

#配置文件项加解密密码,此处是开发环境,实际生产中应该注销,使用启动参数的方式传入
jasypt:
  encryptor:
    password: testtest

spring:
  datasource:
    url: jdbc:......
    username: root
    password: ENC(0RVCs2UAXrb8cWsMk8tJuE6XXMuKZxAHRJ1yP9dA4jdY1MU1jKJumLyVUiF0yvuD)

    ......

3.3 Jasypt 使用测试

通过上边的配置以后,我们就完成了对数据库密码的加密工作,Spring Boot 已经可以正常启动了。更为详细的配置可以参考一下网站:

下边是 Jasypt 的测试例子,实现对信息的加密和解密处理。

package com.**;

import org.jasypt.encryption.StringEncryptor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class UserEncryptorTest {

    @Autowired
    private StringEncryptor stringEncryptor;

    //加密
    @Test
    public void encrypt() {
        System.out.println("testtest 的密文为:"+    stringEncryptor.encrypt("testtest"));
    }

    //解密
    @Test
    public void decrypt() {
        System.out.println("解密结果为:"+stringEncryptor.decrypt("+VZcKfSsRgHuXnosbV55R8elvOHMEoThfgKX+ujJDp0pzMeZLZLK3yrcFWPn2iiO"));
    }

}

//输出结果
//testtest 的密文为:+VZcKfSsRgHuXnosbV55R8elvOHMEoThfgKX+ujJDp0pzMeZLZLK3yrcFWPn2iiO
//解密结果为:testtest

4. 数据源配置

这里使用 MySQL 数据库,使用 JDBC 和 JPA 操作数据库。

4.1 添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

举报

相关推荐

0 条评论