SpringCloud Alibaba微服務(wù)實(shí)戰(zhàn)之業(yè)務(wù)日志組件
本文轉(zhuǎn)載自微信公眾號(hào)「JAVA日知錄」,作者單一色調(diào)。轉(zhuǎn)載本文請(qǐng)聯(lián)系JAVA日知錄公眾號(hào)。
概述
在單體項(xiàng)目中如果我們需要記錄操作日志一般會(huì)通過如下手段實(shí)現(xiàn):
- 建立一個(gè)自定義注解,標(biāo)注業(yè)務(wù)操作類型
- 通過AOP組裝日志實(shí)體,完成日志的收集工作
具體實(shí)現(xiàn)可以參考如下的文章鏈接:
http://javadaily.cn/articles/2020/05/13/1589330750429.html
但是在微服務(wù)架構(gòu)中我們不可能每個(gè)服務(wù)都寫一個(gè)自定義注解,再寫一個(gè)AOP,這很明顯違反了 Don’t repeat yourself 精神。所以這時(shí)候我們一般都會(huì)建立一個(gè)公共的組件,在公共組件中完成日志的收集,后端服務(wù)只需要引入這個(gè)公共的組件即可。
這就是今天文章的內(nèi)容,獨(dú)立的業(yè)務(wù)日志收集組件。
SpringBoot Starter
要實(shí)現(xiàn)上述的功能我們需要借助SringBoot Starter來實(shí)現(xiàn),SpringBoot 的一大優(yōu)勢(shì)就是Starter,通過Starter我們可以封裝公共的業(yè)務(wù)邏輯以及參數(shù)的初始化,如果你在進(jìn)行微服務(wù)開發(fā),Starter的編寫是一定要掌握的。
這里我們簡(jiǎn)單提一下SpringBoot Starter實(shí)現(xiàn)自動(dòng)化配置的流程
- spring-boot啟動(dòng)的時(shí)候會(huì)找到starterjar包中的resources/META-INF/spring.factories文件,根據(jù)spring.factories文件中的配置,找到需要自動(dòng)配置的類,xxxAutoConfigure
- 通過xxxAutoConfigure上的注解@EnableConfigurationProperties將當(dāng)前模塊的屬性綁定到「Environment」 上(若有)。
- 通過xxxAutoConfigure中定義的bean自動(dòng)裝配到IOC容器中。
實(shí)戰(zhàn)
過程如下:
首先我們?cè)陧?xiàng)目中建立一個(gè)starter的module,如cloud-component-logging-starter
編寫配置類SysLogAutoConfigure
- @Configuration
- public class SysLogAutoConfigure {
- @Bean
- public SysLogAspect controllerLogAspect(){
- return new SysLogAspect();
- }
- }
在SysLogAutoConfigure中我們注入了一個(gè)日志切面SysLogAspect,由于日志收集工具不需要額外配置屬性,所以我們也就不需要定義屬性配置類了。
自定義日志注解 SysLog
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface SysLog {
- /**
- * 日志內(nèi)容
- * @return {String}
- */
- String value();
- }
定義日志切面 SysLogAspect
- @Aspect
- public class SysLogAspect {
- private final Logger log = LoggerFactory.getLogger(this.getClass());
- @Pointcut("@annotation(com.javadaily.component.logging.annotation.SysLog)")
- public void logPointCut() {
- }
- @Around("logPointCut()")
- public Object around(ProceedingJoinPoint pjp) throws Throwable {
- MethodSignature signature = (MethodSignature) pjp.getSignature();
- Method method = signature.getMethod();
- //類名
- String className = pjp.getTarget().getClass().getName();
- //方法名
- String methodName = signature.getName();
- SysLog syslog = method.getAnnotation(SysLog.class);
- //操作
- String operator =syslog.value();
- long beginTime = System.currentTimeMillis();
- Object returnValue = null;
- Exception ex = null;
- try {
- returnValue = pjp.proceed();
- return returnValue;
- } catch (Exception e) {
- ex = e;
- throw e;
- } finally {
- long cost = System.currentTimeMillis() - beginTime;
- if (ex != null) {
- log.error("[class: {}][method: {}][operator: {}][cost: {}ms][args: {}][發(fā)生異常]",
- className, methodName, operator, pjp.getArgs(), ex);
- } else {
- log.info("[class: {}][method: {}][operator: {}][cost: {}ms][args: {}][return: {}]",
- className, methodName, operator, cost, pjp.getArgs(), returnValue);
- }
- }
- }
- }
上面的切面表示,對(duì)于使用了@SysLog注解的方法自動(dòng)進(jìn)行日志收集,將日志輸入到日志文件。
在resource/META-INF目錄下建立spring.factories文件,加載配置類SysLogAutoConfigure
- org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- com.javadaily.component.logging.configure.SysLogAutoConfigure
在微服務(wù)中引入日志組件
- <dependency>
- <groupId>com.jianzh5.cloud</groupId>
- <artifactId>cloud-component-logging-starter</artifactId>
- <version>1.0.0</version>
- </dependency>
在需要進(jìn)行日志收集的方法上添加@SysLog注解
- @SysLog("查找用戶")
- public ResultData<AccountDTO> getByCode(@PathVariable(value = "accountCode") String accountCode){
- log.warn("get account detail,accountCode is :{}",accountCode);
- SecurityUser securityUser = SecurityUtils.getUser();
- log.info(securityUser);
- AccountDTO accountDTO = accountService.selectByCode(accountCode);
- return ResultData.success(accountDTO);
- }
小結(jié)
通過上面7步我們完成了日志收集組件的自定義Starter編寫,這里可能有的同學(xué)會(huì)問,在 SysLogAutoConfigure類中不是有了 @Configuration和 @Bean注解,這兩個(gè)注解不是可以自動(dòng)加載定義的Bean到IOC容器嗎?為什么還需要通過在spring.factories文件中導(dǎo)入 SysLogAutoConfigure呢?
這是因?yàn)閟pringboot項(xiàng)目默認(rèn)只會(huì)掃描本項(xiàng)目下的帶@Configuration注解的類,如果自定義starter,不在本工程中,是無法加載的,所以要配置META-INF/spring.factories配置文件,通過spring.factories來裝載配置類。




























