diff --git a/starter-log/.gitignore b/starter-log/.gitignore new file mode 100644 index 0000000..7672b7f --- /dev/null +++ b/starter-log/.gitignore @@ -0,0 +1,10 @@ +/.gradle +/.idea +classes/ +/.settings +/build +/.classpath +/.project +*.iml +**/target + diff --git a/starter-log/pom.xml b/starter-log/pom.xml new file mode 100644 index 0000000..07a2e5d --- /dev/null +++ b/starter-log/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + + com.docus + docus-bom + 1.0-SNAPSHOT + + + starter-log + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-aop + + + + + + + + + + + + + + + diff --git a/starter-log/src/main/java/com/docus/log/EnableTrackGroup.java b/starter-log/src/main/java/com/docus/log/EnableTrackGroup.java new file mode 100644 index 0000000..dd00fd0 --- /dev/null +++ b/starter-log/src/main/java/com/docus/log/EnableTrackGroup.java @@ -0,0 +1,12 @@ +package com.docus.log; + +import org.springframework.context.annotation.Import; + +import java.lang.annotation.*; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Import({EnableTrackGroupSelector.class}) +@Inherited +public @interface EnableTrackGroup { +} diff --git a/starter-log/src/main/java/com/docus/log/EnableTrackGroupConfiguration.java b/starter-log/src/main/java/com/docus/log/EnableTrackGroupConfiguration.java new file mode 100644 index 0000000..fd584b2 --- /dev/null +++ b/starter-log/src/main/java/com/docus/log/EnableTrackGroupConfiguration.java @@ -0,0 +1,15 @@ +package com.docus.log; + +import com.docus.log.aspect.TrackGroupAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class EnableTrackGroupConfiguration { + + @Bean + public TrackGroupAspect logTrackGroupAspect() { + return new TrackGroupAspect(); + } + +} diff --git a/starter-log/src/main/java/com/docus/log/EnableTrackGroupSelector.java b/starter-log/src/main/java/com/docus/log/EnableTrackGroupSelector.java new file mode 100644 index 0000000..d3acc35 --- /dev/null +++ b/starter-log/src/main/java/com/docus/log/EnableTrackGroupSelector.java @@ -0,0 +1,19 @@ +package com.docus.log; + +import org.springframework.context.annotation.ImportSelector; +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.util.Assert; + +public class EnableTrackGroupSelector implements ImportSelector { + + @Override + public String[] selectImports(AnnotationMetadata importingClassMetadata) { + AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(EnableTrackGroup.class.getName(), false)); + Assert.notNull(annotationAttributes, String.format( + "@EnableTrackGroup is not present on importing class '%s' as expected", + importingClassMetadata.getClassName())); + return new String[]{EnableTrackGroupConfiguration.class.getName()}; + } + +} diff --git a/starter-log/src/main/java/com/docus/log/EnableTrackGroupSettings.java b/starter-log/src/main/java/com/docus/log/EnableTrackGroupSettings.java new file mode 100644 index 0000000..8031d89 --- /dev/null +++ b/starter-log/src/main/java/com/docus/log/EnableTrackGroupSettings.java @@ -0,0 +1,5 @@ +package com.docus.log; + +public class EnableTrackGroupSettings { + +} diff --git a/starter-log/src/main/java/com/docus/log/annotation/TrackGroup.java b/starter-log/src/main/java/com/docus/log/annotation/TrackGroup.java new file mode 100644 index 0000000..610af75 --- /dev/null +++ b/starter-log/src/main/java/com/docus/log/annotation/TrackGroup.java @@ -0,0 +1,38 @@ +package com.docus.log.annotation; + +import com.docus.log.processor.ITrackProcessor; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface TrackGroup { + + /** + * 组概念 + */ + String group() default ""; + + /** + * 描述概念 + */ + String desc() default ""; + + /** + * 动作概念 + */ + String action() default ""; + + /** + * 初始化bean概念 + */ + String[] beanNames() default {}; + + /** + * 处理器概念 + */ + Class processor(); +} diff --git a/starter-log/src/main/java/com/docus/log/aspect/TrackGroupAspect.java b/starter-log/src/main/java/com/docus/log/aspect/TrackGroupAspect.java new file mode 100644 index 0000000..bf06ab1 --- /dev/null +++ b/starter-log/src/main/java/com/docus/log/aspect/TrackGroupAspect.java @@ -0,0 +1,110 @@ +package com.docus.log.aspect; + +import com.docus.log.annotation.LogTrackGroup; +import com.docus.log.annotation.TrackGroup; +import com.docus.log.context.TrackContext; +import com.docus.log.context.TrackHelper; +import com.docus.log.processor.ITrackProcessor; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; + +import java.util.HashMap; + +/** + * @author linruifeng + */ +@Aspect +@Slf4j +public class TrackGroupAspect { + + @Autowired + private ApplicationContext applicationContext; + + /** + * 通用业务处理 + */ + @Around("@annotation(trackGroup)") + public Object execute(final ProceedingJoinPoint joinPoint, TrackGroup trackGroup) throws Throwable { + log.debug("=== AOP @TrackGroup 切面启动器监听处理事件开始 ==="); + TrackContext context = getContext(joinPoint, trackGroup); + + ITrackProcessor processor = applicationContext.getAutowireCapableBeanFactory().createBean(trackGroup.processor()); + try { + Object beforeResult = processor.beforeProcess(context); + context.setBeforeResult(beforeResult); + TrackContext.init(context.getParams()); + Object afterReturnResult = joinPoint.proceed(); + context.setAfterReturnResult(afterReturnResult); + TrackHelper.setParams(context.getParams()); + return processor.process(context); + } catch (Exception ex) { + context.setError(true); + context.setExMessageResult(ex.getMessage()); + return processor.process(context); + } finally { + processor.afterProcess(context); + TrackContext.clear(); + log.debug("=== AOP @TrackGroup 切面启动器监听处理事件结束 ==="); + } + } + + /** + * 通用日志处理 + */ + @Around("@annotation(logTrackGroup)") + public Object execute(final ProceedingJoinPoint joinPoint, LogTrackGroup logTrackGroup) throws Throwable { + final Object result; + TrackContext context = getContext(joinPoint, logTrackGroup); + ITrackProcessor processor = applicationContext.getAutowireCapableBeanFactory().createBean(logTrackGroup.processor()); + try { + result = joinPoint.proceed(); + context.setAfterReturnResult(result); + processor.process(context); + } catch (Exception ex) { + context.setError(true); + context.setExMessageResult(ex.getMessage()); + processor.process(context); + throw new RuntimeException(ex.getMessage()); + } + return result; + } + + private TrackContext getContext(final ProceedingJoinPoint joinPoint, TrackGroup logTrackGroup) { + TrackContext context = new TrackContext(); + Signature signature = joinPoint.getSignature(); + context.setClassType(signature.getDeclaringType()); + context.setClassName(signature.getDeclaringTypeName()); + context.setMethodName(signature.getName()); + context.setArgs(joinPoint.getArgs()); + + context.setGroup(logTrackGroup.group()); + context.setDesc(logTrackGroup.desc()); + context.setAction(logTrackGroup.action()); + context.setBeanNames(logTrackGroup.beanNames()); + context.setProcessor(logTrackGroup.processor()); + context.setParams(new HashMap<>()); + return context; + } + + private TrackContext getContext(final ProceedingJoinPoint joinPoint, LogTrackGroup logTrackGroup) { + TrackContext context = new TrackContext(); + Signature signature = joinPoint.getSignature(); + context.setClassType(signature.getDeclaringType()); + context.setClassName(signature.getDeclaringTypeName()); + context.setMethodName(signature.getName()); + context.setArgs(joinPoint.getArgs()); + + context.setGroup(logTrackGroup.group()); + context.setDesc(logTrackGroup.desc()); + context.setAction(logTrackGroup.action()); + context.setProcessor(logTrackGroup.processor()); + context.setParams(new HashMap<>()); + return context; + } + +} diff --git a/starter-log/src/main/java/com/docus/log/context/TrackContext.java b/starter-log/src/main/java/com/docus/log/context/TrackContext.java new file mode 100644 index 0000000..166b472 --- /dev/null +++ b/starter-log/src/main/java/com/docus/log/context/TrackContext.java @@ -0,0 +1,45 @@ +package com.docus.log.context; + +import com.docus.log.processor.ITrackProcessor; +import lombok.Data; + +import java.util.Map; + +@Data +public class TrackContext { + private static final ThreadLocal THREAD_LOCAL = new ThreadLocal<>(); + + private Class classType; + private String className; + private String methodName; + private Object[] args; + + private Object beforeResult; + private Object afterReturnResult; + private boolean error = false; + private String exMessageResult; + + private String group; + private String desc; + private String action; + private String[] beanNames; + private Class processor; + private Map params; + + //初始化 + public static void init(Map params) { + THREAD_LOCAL.remove(); + TrackContext context = new TrackContext(); + context.setParams(params); + THREAD_LOCAL.set(context); + } + + public static TrackContext get() { + return THREAD_LOCAL.get(); + } + + //清除线程变量 + public static void clear() { + THREAD_LOCAL.remove(); + } +} diff --git a/starter-log/src/main/java/com/docus/log/processor/AbstractProcessor.java b/starter-log/src/main/java/com/docus/log/processor/AbstractProcessor.java new file mode 100644 index 0000000..e34cdea --- /dev/null +++ b/starter-log/src/main/java/com/docus/log/processor/AbstractProcessor.java @@ -0,0 +1,70 @@ +package com.docus.log.processor; + +import com.docus.log.context.TrackContext; +import com.docus.log.context.TrackHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractProcessor implements ITrackProcessor { + + private final Logger logger = LoggerFactory.getLogger(AbstractProcessor.class); + + public boolean validate(TrackContext context) { + return context != null + && context.getGroup() != null + && context.getProcessor() != null; + } + + /** + * 前置通知 + */ + @Override + public Object beforeProcess(TrackContext context) { + logger.debug("=== AOP 前置通知 ==="); + return null; + } + + /** + * 后置通知和异常通知 + */ + @Override + public Object process(TrackContext context) { + if (validate(context)) { + Object o = doProcess(context); + TrackHelper.setParams(context.getParams()); + return o; + } + return null; + } + + /** + * 最后通知 + */ + @Override + public Object afterProcess(TrackContext context) { + logger.debug("=== AOP 最后通知 ==="); + return null; + } + + public Object doProcess(TrackContext context) { + if (context.isError()) { + logger.debug("=== AOP 异常通知 ==="); + return afterThrowingProcess(context); + } else { + logger.debug("=== AOP 后置通知 ==="); + return afterReturnProcess(context); + } + } + + /** + * 后置通知 + */ + protected abstract Object afterReturnProcess(TrackContext context); + + /** + * 异常通知 + */ + protected abstract Object afterThrowingProcess(TrackContext context); + + +} diff --git a/starter-log/src/main/java/com/docus/log/processor/ITrackProcessor.java b/starter-log/src/main/java/com/docus/log/processor/ITrackProcessor.java new file mode 100644 index 0000000..dd172b0 --- /dev/null +++ b/starter-log/src/main/java/com/docus/log/processor/ITrackProcessor.java @@ -0,0 +1,12 @@ +package com.docus.log.processor; + +import com.docus.log.context.TrackContext; + +public interface ITrackProcessor { + + Object beforeProcess(TrackContext context); + + Object process(TrackContext context); + + Object afterProcess(TrackContext context); +}