Explorar el Código

Merge tag '1.6.4' into develop

Tagging version 1.6.4 1.6.4
tianyunperfect hace 4 años
padre
commit
d207eefc21

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 # 版本升级日志
 
+## 1.6.4 - 2020年10月23日
+
+- 规范项目和模块命名规则
+
 ## 1.6.3 - 2020年10月22日
 
 - 添加docker脚本

+ 11 - 0
springboot-main/Dockerfile

@@ -0,0 +1,11 @@
+FROM hub.c.163.com/library/java:8-alpine
+VOLUME /tmp
+ADD target/*.jar app.jar
+
+# 抛出端口,起标记作用
+EXPOSE 8080
+
+#启动命令
+ENTRYPOINT exec java -jar app.jar
+# 默认参数
+#CMD [""]

+ 159 - 0
springboot-main/bin/boot.sh

@@ -0,0 +1,159 @@
+#!/bin/bash
+#jar包名称初始化,不用手动设置
+APP_NAME=
+# 切换目录
+cd `dirname $0` || exit
+cd ..
+
+#查找jar包
+for item in *.jar; do
+  fileName=$item
+  if [ -f "$fileName" ]; then
+    if [ "${fileName##*.}" = jar ]; then
+      APP_NAME=$fileName
+      break
+    fi
+  fi
+done
+
+if [ ! "$APP_NAME" ]; then
+  echo 未找到jar包
+  exit 1
+fi
+
+STDOUT_FILE=/dev/null
+
+
+# 判断java是否存在
+BITS=$(java -version 2>&1 | grep -i 64-bit)
+if [ -z "$BITS" ]; then
+  echo 未安装JDK8
+  exit 1
+fi
+
+# 解锁更多参数、
+JAVA_OPTS=" -XX:+UnlockExperimentalVMOptions"
+# 内存配置,监视程序,然后根据实际情况进行调整,元空间默认20兆左右
+# -Xms8g -Xmx8g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m
+JAVA_OPTS="$JAVA_OPTS -server "
+# 垃圾收集器、设置分层编译、
+JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:+TieredCompilation"
+# 自定义配置文件和lib目录,多个目录用冒号分割
+# 已修改为分离 lib和 resource,所以 Dloader.path暂时不用
+#JAVA_OPTS="$JAVA_OPTS -Dloader.path=config -Djava.io.tmpdir=./tmp "
+JAVA_OPTS="$JAVA_OPTS -Djava.io.tmpdir=./tmp "
+# 服务器模式、兼容IPV4、编码(避免乱码)、禁止代码调用gc、
+JAVA_OPTS="$JAVA_OPTS -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8  -XX:+DisableExplicitGC"
+# gc 日志
+JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:log/gc.log "
+# OOM日志
+JAVA_OPTS="$JAVA_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=log/heap_dump"
+
+# java调试
+if [ "$2" = "debug" ]; then
+  JAVA_OPTS="$JAVA_OPTS -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8081 "
+fi
+
+
+# 使用说明,用来提示输入参数
+usage() {
+  echo "Usage: sh boot [APP_NAME] [start|stop|restart|status]"
+  exit 1
+}
+
+# 检查程序是否在运行
+is_exist() {
+  # 获取PID
+  PID=$(ps -ef | grep ${APP_NAME} | grep -v $0 | grep -v grep | awk '{print $2}')
+  # -z "${pid}"判断pid是否存在,如果不存在返回1,存在返回0
+  if [ -z "${PID}" ]; then
+    # 如果进程不存在返回1
+    return 1
+  else
+    # 进程存在返回0
+    return 0
+  fi
+}
+
+# 定义启动程序函数
+start() {
+  is_exist
+  if [ $? -eq "0" ]; then
+    echo "${APP_NAME} is already running, PID=${PID}"
+  else
+    nohup java -jar $JAVA_OPTS ${APP_NAME} >>${STDOUT_FILE} 2>&1 &
+    PID=$(echo $!)
+    echo "${APP_NAME} start success, PID=$!"
+  fi
+}
+
+# docker_start 前台运行
+docker_start() {
+  is_exist
+  if [ $? -eq "0" ]; then
+    echo "${APP_NAME} is already running, PID=${PID}"
+  else
+    java -jar $JAVA_OPTS ${APP_NAME} >>${STDOUT_FILE} 2>&1
+    PID=$(echo $!)
+    echo "${APP_NAME} start success, PID=$!"
+  fi
+}
+
+# 停止进程函数
+stop() {
+  is_exist
+  if [ $? -eq "0" ]; then
+    kill -9 "${PID}"
+    # 检测是否停止
+    COUNT=1
+    while [ $COUNT -eq 1 ]; do
+      echo -e ".\c"
+      sleep 1
+      is_exist
+      if [ -z "${PID}" ]; then
+        COUNT=0
+        echo "${APP_NAME} process stop"
+      fi
+    done
+  else
+    echo "There is not the process of ${APP_NAME}"
+  fi
+}
+
+# 重启进程函数
+restart() {
+  stop
+  start
+}
+
+# 查看进程状态
+status() {
+  is_exist
+  if [ $? -eq "0" ]; then
+    echo "${APP_NAME} is running, PID=${PID}"
+  else
+    echo "There is not the process of ${APP_NAME}"
+  fi
+}
+
+case $1 in
+"start")
+  start
+  ;;
+"docker_start")
+  start
+  ;;
+"stop")
+  stop
+  ;;
+"restart")
+  restart
+  ;;
+"status")
+  status
+  ;;
+*)
+  usage
+  ;;
+esac
+exit 0

+ 1 - 0
springboot-main/bin/docker-build

@@ -0,0 +1 @@
+#!/bin/bash

cd `dirname $0`
cd ..

# 定义应用组名
group_name='springboot-parent'
# 定义应用名称
app_name='app'
# 定义应用版本
app_version='1.0-SNAPSHOT'
# 定义应用环境
profile_active='dev'
echo '----copy jar----'
docker stop ${app_name}
echo '----stop container----'
docker rm ${app_name}
echo '----rm container----'
docker rmi ${group_name}/${app_name}:${app_version}
echo '----rm image----'
# 打包编译docker镜像
docker build -t ${group_name}/${app_name}:${app_version} .
echo '----build image----'
docker run -p 8080:8080 --name ${app_name} \
-e 'spring.profiles.active'=${profile_active} \
-d ${group_name}/${app_name}:${app_version}
echo '----start container----'

+ 19 - 0
springboot-main/bin/push.sh

@@ -0,0 +1,19 @@
+mvn clean package -Dmaven.test.skip=true
+
+remote=root@www.xxx.cn
+remoteDir=/app/appName/
+
+# 在本地执行的代码,比如上传文件到服务器 scp 本地文件 user@ip:远程目录
+scp -r app/target/lib ${remote}:${remoteDir}
+scp -r app/target/resource ${remote}:${remoteDir}
+scp app/target/*.jar ${remote}:${remoteDir}
+
+# 执行命令
+ssh -o StrictHostKeyChecking=no ${remote} > /dev/null 2>&1 << eeooff
+
+cd /app/appName/
+sh bin/boot.sh restart
+
+exit
+eeooff
+echo ok

+ 153 - 0
springboot-main/pom.xml

@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>springboot-parent</artifactId>
+        <groupId>com.alvin.springboot</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>springboot-main</artifactId>
+
+    <build>
+        <plugins>
+            <!-- 分离lib -->
+            <plugin>
+                <!--这个插件就是把依赖的jar包复制出来放到编译后的target/lib目录,并且在打包时候排除内部依赖-->
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
+                            <overWriteReleases>false</overWriteReleases>
+                            <overWriteSnapshots>false</overWriteSnapshots>
+                            <overWriteIfNewer>true</overWriteIfNewer>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- 分离资源文件 -->
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-resources</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <resources>
+                                <resource>
+                                    <directory>src/main/resources</directory>
+                                </resource>
+                            </resources>
+                            <outputDirectory>${project.build.directory}/resources</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!--打包jar-->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <!-- 指定资源文件目录,与打包的jar文件同级目录 -->
+                        <manifestEntries>
+                            <Class-Path>resources/</Class-Path>
+                        </manifestEntries>
+                        <manifest>
+                            <addClasspath>true</addClasspath>
+                            <classpathPrefix>lib/</classpathPrefix>
+                            <mainClass>com.alvin.Application</mainClass>
+                        </manifest>
+                    </archive>
+                    <!-- 打包时忽略的文件(也就是不打进jar包里的文件),本例将resources下的.yml、.xml、.db文件全部排除 -->
+                    <excludes>
+                        <exclude>**/*.yml</exclude>
+                        <exclude>**/*.xml</exclude>
+                        <exclude>**/*.db</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <!-- spring boot repackage -->
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <layout>ZIP</layout>
+                    <includes>
+                        <include>
+                            <groupId>non-exists</groupId>
+                            <artifactId>non-exists</artifactId>
+                        </include>
+                    </includes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <!--排除logback-->
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <scope>runtime</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <!--log4j2 依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-log4j2</artifactId>
+        </dependency>
+        <!--异步日志依赖-->
+        <dependency>
+            <groupId>com.lmax</groupId>
+            <artifactId>disruptor</artifactId>
+            <version>3.3.7</version>
+        </dependency>
+
+        <!--dao层mybatis-->
+        <dependency>
+            <groupId>com.alvin.springboot</groupId>
+            <artifactId>springboot-dao</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 23 - 0
springboot-main/src/main/java/com/alvin/Application.java

@@ -0,0 +1,23 @@
+package com.alvin;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@MapperScan("com.alvin.dao.mapper")
+public class Application implements CommandLineRunner {
+    public static void main(String[] args) {
+        //日志异步
+        System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
+        SpringApplication.run(Application.class, args);
+    }
+
+
+
+    @Override
+    public void run(String... args) throws Exception {
+        System.out.println("启动成功");
+    }
+}

+ 55 - 0
springboot-main/src/main/java/com/alvin/aspect/LogAspect.java

@@ -0,0 +1,55 @@
+package com.alvin.aspect;
+
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * 日志切片
+ *
+ * @author tianyunperfect
+ * Created on 2019/9/19
+ */
+@Component
+@Aspect
+@Slf4j
+public class LogAspect {
+
+    @Pointcut("execution(public * com.alvin.controller..*.*(..))")
+    public void webLog() {
+    }
+
+    @Around("webLog()")
+    public Object webAop(ProceedingJoinPoint joinPoint) throws Throwable {
+        /*
+         * 执行方法之前
+         */
+        long start = System.currentTimeMillis();
+        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+        /*
+         * 执行方法
+         */
+        Object result = joinPoint.proceed();
+        /*
+         * 执行方法之后
+         */
+        String split = "; ";
+        String sb = "url=" + request.getRequestURL() + split +
+                "method=" + request.getMethod() + split +
+                "class_method=" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() + split +
+                "args=" + Arrays.toString(joinPoint.getArgs()) + split +
+                "consumer time(ms) = " + (System.currentTimeMillis() - start);
+        log.info(sb);
+
+        return result;
+    }
+}

+ 47 - 0
springboot-main/src/main/java/com/alvin/config/LongToStringJsonConfig.java

@@ -0,0 +1,47 @@
+package com.alvin.config;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
+
+import java.util.List;
+
+/**
+ * 我们把long类型数据传到前端时,会丢失精度,这里加一个配置类即可将long转换为string
+ *
+ * @author tianyunperfect
+ * @date 2020/05/20
+ */
+@Configuration
+public class LongToStringJsonConfig extends WebMvcConfigurationSupport {
+
+    /**
+     * 这个必须有,否则不能访问静态文件
+     * @param configurer
+     */
+    @Override
+    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
+        configurer.enable();
+    }
+
+    /**
+     * 配置Long转string
+     * @param converters
+     */
+    @Override
+    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+        MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
+        ObjectMapper objectMapper = new ObjectMapper();
+        SimpleModule simpleModule = new SimpleModule();
+        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
+        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
+        objectMapper.registerModule(simpleModule);
+        jackson2HttpMessageConverter.setObjectMapper(objectMapper);
+        converters.add(jackson2HttpMessageConverter);
+    }
+}

+ 41 - 0
springboot-main/src/main/java/com/alvin/controller/AppController.java

@@ -0,0 +1,41 @@
+package com.alvin.controller;
+
+import com.alvin.common.entity.PageResult;
+import com.alvin.common.entity.Result;
+import com.alvin.entity.User;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Collections;
+
+@Slf4j
+@RestController
+@RequestMapping("/user")
+public class AppController {
+
+    /**
+     * 找到一个
+     *
+     * @return {@link Result<User>}
+     */
+    @GetMapping("/findOne")
+    public Result<User> findOne() {
+        User user = new User();
+        user.setName("小米");
+        user.setAge(18);
+        log.info(user.toString());
+        return Result.success(user);
+    }
+
+    @GetMapping("/queryPage")
+    public Result<PageResult<User>> queryPage() {
+        User user = new User();
+        user.setName("小米");
+        user.setAge(18);
+        PageResult<User> pageResult = new PageResult<>(1, 10, 100L, Collections.singletonList(user));
+        return Result.success(pageResult);
+    }
+
+}

+ 9 - 0
springboot-main/src/main/java/com/alvin/entity/User.java

@@ -0,0 +1,9 @@
+package com.alvin.entity;
+
+import lombok.Data;
+
+@Data
+public class User {
+    private String name;
+    private Integer age;
+}

+ 32 - 0
springboot-main/src/main/java/com/alvin/handle/ExceptionHandle.java

@@ -0,0 +1,32 @@
+package com.alvin.handle;
+
+import com.alvin.common.entity.Result;
+import com.alvin.common.entity.ResultCode;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+/**
+ * Class ExceptionHandle ...
+ *s
+ * @author tianyunperfect
+ * Created on 2019/9/19
+ */
+@ControllerAdvice
+@Slf4j
+public class ExceptionHandle {
+
+    /**
+     * 统一异常处理
+     * @param e
+     * @return
+     */
+    @ResponseBody
+    @ExceptionHandler
+    public Result exceptionHandle(Exception e) {
+        e.printStackTrace();
+        log.error("系统异常:{}", e.toString());
+        return Result.failure(ResultCode.UNKNOW.ordinal(), e.getMessage());
+    }
+}

+ 51 - 0
springboot-main/src/main/resources/application-dev.yml

@@ -0,0 +1,51 @@
+server:
+  port: 8080
+
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://ip-191:3306/biaozhu_medical_kg?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
+    username: xxx
+    password: xxx
+    #下面为连接池补充设置
+    druid:
+      initial-size: 5 # 初始化
+      max-active: 5 # 最大
+      min-idle: 5 # 最小
+      max-wait: 6000 # 超时时间
+      time-between-eviction-runs-millis: 60000 # 每分钟检查一次空闲链接
+      min-evictable-idle-time-millis: 300000 # 空闲链接可以保持多久而不被驱逐
+      # 检测链接是否有效的query
+      validation-query: SELECT 1 FROM DUAL
+      test-while-idle: true # 检测到链接空闲时,验证是否有效
+      test-on-borrow: false # 申请链接时,不检测
+      test-on-return: false # 返回链接时,不检测
+      pool-prepared-statements: false # 是否缓存preparedStatement,oracle打开,mysql关闭
+      # 如果上面开启了游标,这里要设置一下大小,例如 50
+      max-pool-prepared-statement-per-connection-size: -1
+      # 统计、监控配置
+      filters: stat,wall # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
+      # 合并执行的相同sql,避免因为参数不同而统计多条sql语句;开启慢sql记录
+      connect-properties: config.stat.mergeSql=true;config.stat.slowSqlMillis=500
+      use-global-data-source-stat: true # 合并多个DruidDataSource的监控数据
+      stat-view-servlet:
+        enabled: true
+        login-username: tianyun
+        login-password: tianyunperfect
+        allow: # 默认运行所有
+        deny: # 默认即可
+        reset-enable: true
+
+
+mybatis:
+  type-aliases-package: com.alvin.dao.entity
+  mapper-locations: classpath:mapper/*Mapper.xml
+
+
+# 设置debug模式下打印mysql
+logging:
+  level:
+    com:
+      alvin:
+        mapper: debug

+ 2 - 0
springboot-main/src/main/resources/application-docker.yml

@@ -0,0 +1,2 @@
+server:
+  port: 8080

+ 35 - 0
springboot-main/src/main/resources/application-prod.yml

@@ -0,0 +1,35 @@
+server:
+  port: 8080
+
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://127.0.0.1:3306/user?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
+    username:
+    password:
+    #下面为连接池补充设置
+    initialSize: 5
+    # 配置获取连接等待超时的时间
+    maxWait: 60000
+    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+    timeBetweenEvictionRunsMillis: 60000
+    # 配置一个连接在池中最小生存的时间,单位是毫秒
+    minEvictableIdleTimeMillis: 300000
+    validationQuery: SELECT 1 FROM DUAL
+    testWhileIdle: true
+    testOnBorrow: false
+    testOnReturn: false
+    # 打开PSCache,并且指定每个连接上PSCache的大小
+    poolPreparedStatements: true
+    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
+    filters: stat,wall
+    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
+    connectionProperties: config.stat.mergeSql=true;config.stat.slowSqlMillis=5000
+    # 合并多个DruidDataSource的监控数据
+    useGlobalDataSourceStat: true
+
+
+mybatis:
+  type-aliases-package: com.alvin.dao.entity
+  mapper-locations: classpath:mapper/*Mapper.xml

+ 5 - 0
springboot-main/src/main/resources/application.yml

@@ -0,0 +1,5 @@
+spring:
+  profiles:
+    active: dev
+server:
+  port: 8080

+ 67 - 0
springboot-main/src/main/resources/log4j2.xml

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
+<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
+<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
+<configuration status="WARN" monitorInterval="30">
+    <properties>
+        <property name="logDir" value="log"/>
+    </properties>
+    <!--先定义所有的appender-->
+    <appenders>
+        <!--这个输出控制台的配置-->
+        <console name="Console" target="SYSTEM_OUT">
+            <!--输出日志的格式-->
+            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+        </console>
+        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
+        <File name="log" fileName="${logDir}/test.log" append="false">
+            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
+        </File>
+        <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
+        <RollingRandomAccessFile name="RollingFileInfo" fileName="${logDir}/info.log"
+                     filePattern="${logDir}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"
+                                 immediateFlush="false">
+            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
+            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
+            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+            <Policies>
+                <TimeBasedTriggeringPolicy/>
+                <SizeBasedTriggeringPolicy size="500 MB"/>
+            </Policies>
+        </RollingRandomAccessFile>
+        <RollingRandomAccessFile name="RollingFileWarn" fileName="${logDir}/warn.log"
+                     filePattern="${logDir}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log"
+                                 immediateFlush="false">
+            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
+            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+            <Policies>
+                <TimeBasedTriggeringPolicy/>
+                <SizeBasedTriggeringPolicy size="500 MB"/>
+            </Policies>
+            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
+            <DefaultRolloverStrategy max="20"/>
+        </RollingRandomAccessFile>
+        <RollingRandomAccessFile name="RollingFileError" fileName="${logDir}/error.log"
+                     filePattern="${logDir}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log"
+                                 immediateFlush="false">
+            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
+            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+            <Policies>
+                <TimeBasedTriggeringPolicy/>
+                <SizeBasedTriggeringPolicy size="500 MB"/>
+            </Policies>
+        </RollingRandomAccessFile>
+    </appenders>
+    <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
+    <loggers>
+        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
+        <logger name="org.springframework" level="INFO"/>
+        <logger name="org.mybatis" level="INFO"/>
+        <root level="all" includeLocation="true">
+            <appender-ref ref="Console"/>
+            <appender-ref ref="RollingFileInfo"/>
+            <appender-ref ref="RollingFileWarn"/>
+            <appender-ref ref="RollingFileError"/>
+        </root>
+    </loggers>
+</configuration>

+ 29 - 0
springboot-main/src/test/java/com/alvin/controller/AppControllerTest.java

@@ -0,0 +1,29 @@
+package com.alvin.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+
+import java.util.Date;
+
+@Slf4j
+public class AppControllerTest extends TestBase {
+
+    @Test
+    public void testFindOne() throws Exception {
+        mockMvc.perform(
+                MockMvcRequestBuilders.get("/user/findOne")
+                .contentType(MediaType.APPLICATION_JSON_UTF8)
+        )
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andReturn();
+        //System.out.println(mvcResult.getResponse().getContentAsString());
+    }
+
+    @Test
+    public void testLog() {
+        log.info(new Date().toString());
+    }
+}

+ 37 - 0
springboot-main/src/test/java/com/alvin/controller/TestBase.java

@@ -0,0 +1,37 @@
+package com.alvin.controller;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+
+
+/**
+ * 测试基础类,建议测试service层
+ *
+ * @author tianyunperfect
+ * @date 2020/05/20
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@WebAppConfiguration
+@AutoConfigureMockMvc
+public class TestBase {
+    @Autowired
+    protected MockMvc mockMvc;
+
+    @Before
+    public void init() {
+        System.out.println("开始测试-----------------");
+    }
+
+    @After
+    public void after() {
+        System.out.println("测试结束-----------------");
+    }
+}