【无限列车1】SpringCloudAlibaba 与 SpringBoot后端架构的搭建
- 1、版本说明
- 二、日志相关配置
- 3、AOP 打印日志
- 4、下载开源前端后台管理系统
- 5、添加网关模块
- 6、集成数据库和mp
- (1) 添加驱动和mp依赖
- (2) 数据库配置
- (3) 使用MybatisPlus
- 7、加密 yaml 文件中的内容
- (1) 依赖
- (2) 敏感信息加密
- (3) 把(2)中的加密字符串放到配置文件中
1、版本说明
【SpringCloud 版本说明】https://sca.aliyun.com/zh-cn/docs/2022.0.0.0-RC1/overview/version-explain
🖊 RC(Release Candidate):发布候选版本(不再加入新功能,侧重改 BUG)
<?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"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.0</version><relativePath/></parent><!-- 打包方式 --><packaging>pom</packaging><groupId>com.jagochan</groupId><artifactId>unlimited-train-backend</artifactId><version>1.0.0</version><properties><java.version>17</java.version><spring-cloud.version>2022.0.0</spring-cloud.version><spring-cloud-alibaba.version>2022.0.0.0-RC1</spring-cloud-alibaba.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
</project>
二、日志相关配置
🖊 新增会员模块(member)
@SpringBootApplication
public class TrainMemberApplication {private static final Logger LOG = LoggerFactory.getLogger(TrainMemberApplication.class);@SuppressWarnings("all")public static void main(String[] args) {ConfigurableApplicationContext ioc = SpringApplication.run(TrainMemberApplication.class, args);ConfigurableEnvironment env = ioc.getEnvironment();// http://www.network-science.de/ascii/LOG.info("\n _ _ \n" +" | | | | \n" +" | | __ _ __ _ ___ ___| |__ __ _ _ __ \n" +" _ | |/ _` |/ _` |/ _ \\ / __| '_ \\ / _` | '_ \\ \n" +"| |__| | (_| | (_| | (_) | (__| | | | (_| | | | |\n" +" \\____/ \\__,_|\\__, |\\___/ \\___|_| |_|\\__,_|_| |_|\n" +" __/ | \n" +" |___/ \n" +"会员模块启动成功(*^_^*) \n" +"BaseURL: http://{}:{}{}", env.getProperty("server.address"),env.getProperty("server.port"),env.getProperty("server.servlet.context-path"));}
}
📕 logback-spring.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<configuration><!-- 修改一下路径--><property name="PATH" value="./log/member"/><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><!--<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %blue(%-50logger{50}:%-4line) %thread %green(%-18X{LOG_ID}) %msg%n</Pattern>--><Pattern>%d{mm:ss.SSS} %highlight(%-5level) %blue(%-30logger{30}:%-4line) %thread %green(%-18X{LOG_ID})%msg%n</Pattern></encoder></appender><appender name="TRACE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${PATH}/trace.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><FileNamePattern>${PATH}/trace.%d{yyyy-MM-dd}.%i.log</FileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>10MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><layout><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-50logger{50}:%-4line %green(%-18X{LOG_ID}) %msg%n</pattern></layout></appender><appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${PATH}/error.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><FileNamePattern>${PATH}/error.%d{yyyy-MM-dd}.%i.log</FileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>10MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><layout><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-50logger{50}:%-4line %green(%-18X{LOG_ID}) %msg%n</pattern></layout><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><root level="ERROR"><appender-ref ref="ERROR_FILE"/></root><root level="TRACE"><appender-ref ref="TRACE_FILE"/></root><root level="INFO"><appender-ref ref="STDOUT"/></root>
</configuration>
3、AOP 打印日志
📕 maven 依赖
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.70</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.6.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>3.0.0</version>
</dependency>
📕 切面类
@Aspect
@Component
public class LogAspect {private final static Logger LOG = LoggerFactory.getLogger(LogAspect.class);@Pointcut("execution(public * com.jagochan..*Controller.*(..))")public void controllerPointcut() {}@Before("controllerPointcut()")public void doBefore(JoinPoint joinPoint) {// 开始打印请求日志ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();Signature signature = joinPoint.getSignature();String name = signature.getName();// 打印请求信息LOG.info("------------- 开始 -------------");LOG.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());LOG.info("类名方法: {}.{}", signature.getDeclaringTypeName(), name);LOG.info("远程地址: {}", request.getRemoteAddr());// 打印请求参数Object[] args = joinPoint.getArgs();// 排除特殊类型的参数,如文件类型Object[] arguments = new Object[args.length];for (int i = 0; i < args.length; i++) {if (args[i] instanceof ServletRequest|| args[i] instanceof ServletResponse|| args[i] instanceof MultipartFile) {continue;}arguments[i] = args[i];}// 排除字段,敏感字段或太长的字段不显示:身份证、手机号、邮箱、密码等String[] excludeProperties = {};PropertyPreFilters filters = new PropertyPreFilters();PropertyPreFilters.MySimplePropertyPreFilter excludeFilter = filters.addFilter();excludeFilter.addExcludes(excludeProperties);LOG.info("请求参数: {}", JSONObject.toJSONString(arguments, excludeFilter));}@Around("controllerPointcut()")public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {long startTime = System.currentTimeMillis();Object result = proceedingJoinPoint.proceed();// 排除字段,敏感字段或太长的字段不显示:身份证、手机号、邮箱、密码等String[] excludeProperties = {};PropertyPreFilters filters = new PropertyPreFilters();PropertyPreFilters.MySimplePropertyPreFilter excludeFilter = filters.addFilter();excludeFilter.addExcludes(excludeProperties);LOG.info("返回结果: {}", JSONObject.toJSONString(result, excludeFilter));LOG.info("------------- 结束 耗时:{} ms -------------", System.currentTimeMillis() - startTime);return result;}}
4、下载开源前端后台管理系统
# clone the project
git clone https://github.com/PanJiaChen/vue-admin-template.git# enter the project directory
cd vue-admin-template# install dependency
npm install# develop
npm run dev
5、添加网关模块
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>
📕 TrainGatewayApplication.java
spring:cloud:gateway:routes:- id: memberuri: http://127.0.0.1:5200predicates:- Path=/member/**
📕 添加JVM参数,让请求有日志
-Dreactor.netty.http.server.accessLogEnabled=true
6、集成数据库和mp
(1) 添加驱动和mp依赖
<!-- MySql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.22</version></dependency><!-- MyBatisPlus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version></dependency>
(2) 数据库配置
spring:application:name: train-memberdatasource:url: jdbc:mysql://gqok.xyz:3306/unlimited_train?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver
(3) 使用MybatisPlus
- MemberMapper 继承 BaseMapper
- MemberService 继承 IService
- MemberServiceImpl 继承 ServiceImpl
7、加密 yaml 文件中的内容
(1) 依赖
<dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>2.1.0</version></dependency>
(2) 敏感信息加密
/*** 对配置文件中的敏感信息做加密处理*/
public class JasyptUtil {public static void main(String[] args) {StandardPBEStringEncryptor stringEncryptor = new StandardPBEStringEncryptor();// 设置加密密钥(该密钥用于解密和加密)// 项目启动的时候要在JVM参数中配置stringEncryptor.setPassword("thePwdIsUsedToEncrypt");// 设置加密算法stringEncryptor.setAlgorithm("PBEWithMD5AndDES");// 对username进行加密处理, 加密后的字符串是密文, 要放到配置文件中String username = stringEncryptor.encrypt("username");System.out.println("🍀 username = " + username);// 对password进行加密处理, 加密后的字符串是密文, 要放到配置文件中String pwd = stringEncryptor.encrypt("password");System.out.println("🍀 pwd = " + pwd);}
}
(3) 把(2)中的加密字符串放到配置文件中
📕 加密字符串需要用 ENC()
包裹
🖊 如:ENC(thisIsASecret)
spring:application:name: train-memberdatasource:url: jurl: jdbc:mysql://happy.xyz:3306/unlimited_train?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=falseusername: ENC(WWGfxe/CgyS4YnyCIZJvuXHbBn5D2y3XWlTmlKMA0mc=)password: ENC(8LARw5u9e9MkXTh/ZoxuFE8bIoUjwVMc/uDoKnriaZo=)driver-class-name: com.mysql.cj.jdbc.Driverjasypt:encryptor:algorithm: PBEWithMD5AndDES
🖊 启动项目的时候要加 JVM 参数,配置解密密钥:
-Djasypt.encryptor.password=password
🖊 添加启动注解:
@EnableEncryptableProperties