在上一篇“SpringBoot 使用@Aspect进行日志管理(基于反射代理模式+注解Log)”的基础上,添加注解进行日志管理升级版
1、修改日志注解类
/**
* 日志注解
* Created by 陈梓平 on 2017/9/7.
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface JournalLog {
/** 要执行的操作类型比如:add **/
int operationType() default -1;
/** 要执行的模块名称如:Carouse **/
int modularTypeName() default -1;
/**注解说明*/
String xplain() default "";
/**判断类型*/
boolean checkBoolean() default false;
/**注解说明数组*/
String[] xplainArray() default "";
}
2、添加注解工具类
/**
* 注解工具类
* Created by 陈梓平 on 2017/9/11.
*/
public class AnnotationUtils {
/**日志输出*/
private static final Logger logger = LoggerFactory.getLogger(AnnotationUtils.class);
private static AnnotationUtils mInstance;
public AnnotationUtils() {
}
public static AnnotationUtils get() {
if (mInstance == null) {
synchronized (AnnotationUtils.class) {
if (mInstance == null) {
mInstance = new AnnotationUtils();
}
}
}
return mInstance;
}
/**
* 获取注解属性值信息
* @param className 类名
* @param methodName 方法名
* @param annotationClass 注解类
* @param attrName 注解属性名
* @throws NotFoundException
*/
public static Object getAnnotationAttr(String className,String methodName,Class<?> annotationClass,String attrName) throws NotFoundException, NoSuchMethodException {
Object value = null;
if (StringUtils.isBlank(className))
return value;
if (StringUtils.isBlank(methodName))
return value;
if (annotationClass==null)
return value;
if (StringUtils.isBlank(attrName))
return value;
ClassPool pool = ClassPool.getDefault();
//获取要修改的类的所有信息
CtClass ct = pool.get(className);
CtMethod ctMethod = ct.getDeclaredMethod(methodName);
MethodInfo methodInfo = ctMethod.getMethodInfo();
//获取注解属性
AnnotationsAttribute attribute = (AnnotationsAttribute) methodInfo.getAttribute(AnnotationsAttribute.visibleTag);
String annotationName = annotationClass.getName();
Method operationType = annotationClass.getDeclaredMethod(attrName);
Class<?> returnType = operationType.getReturnType();
if (attribute!=null){
//获取注解
Annotation annotation = attribute.getAnnotation(annotationName);
if (annotation!=null){
//获取注解的值
if (int.class.isAssignableFrom(returnType)){
IntegerMemberValue memberValue = (IntegerMemberValue) annotation.getMemberValue(attrName);
if (memberValue!=null)
value = memberValue.getValue() ;
}
if (String.class.isAssignableFrom(returnType)){
StringMemberValue memberValue = (StringMemberValue) annotation.getMemberValue(attrName);
if (memberValue!=null)
value = memberValue .getValue() ;
}
if (boolean.class.isAssignableFrom(returnType)){
BooleanMemberValue memberValue = (BooleanMemberValue) annotation.getMemberValue(attrName);
if (memberValue!=null)
value = memberValue.getValue() ;
}
if (String[].class.isAssignableFrom(returnType)){
ArrayMemberValue memberValue = (ArrayMemberValue) annotation.getMemberValue(attrName);
if (memberValue!=null){
MemberValue[] strValueArray = memberValue.getValue();
String[] strValueA = new String[strValueArray.length];
for (int i = 0;i<strValueArray.length;i++){
StringMemberValue stringMemberValue = (StringMemberValue) strValueArray[i];
strValueA[i] = stringMemberValue.getValue();
}
value = strValueA;
}
}
}
}
return value;
}
/**
* 修改注解属性
* @param className 类名
* @param methodName 方法名
* @param annotationClass 注解名
* @param attrName 属性名
* @param value 修改值
* @throws NotFoundException
*/
public static boolean updateAnnotationAttr(String className,String methodName,Class<?> annotationClass,String attrName,Object value) throws NotFoundException, NoSuchMethodException {
if (StringUtils.isBlank(className))
return false;
if (StringUtils.isBlank(methodName))
return false;
if (annotationClass==null)
return false;
if (StringUtils.isBlank(attrName))
return false;
if (value==null)
return false;
ClassPool pool = ClassPool.getDefault();
//获取需要修改的类
CtClass ct = pool.get(className);
CtMethod minInfo = ct.getDeclaredMethod(methodName);
MethodInfo methodInfo = minInfo.getMethodInfo();
ConstPool cp = methodInfo.getConstPool();
AnnotationsAttribute attribute = new AnnotationsAttribute(cp, AnnotationsAttribute.visibleTag);
String annotationName = annotationClass.getName();
Method operationType = annotationClass.getDeclaredMethod(attrName);
Class<?> returnType = operationType.getReturnType();
Annotation annotation = new Annotation(annotationName, cp);
//修改名称为unitName的注解
if (annotation != null) {
if (String.class.isAssignableFrom(returnType))
annotation.addMemberValue(attrName, new StringMemberValue((String) value, cp));
else if (int.class.isAssignableFrom(returnType))
annotation.addMemberValue(attrName, new IntegerMemberValue(cp,(Integer)value));
else if (boolean.class.isAssignableFrom(returnType))
annotation.addMemberValue(attrName, new BooleanMemberValue((boolean) value, cp));
else if (String[].class.isAssignableFrom(returnType)){
String[] stres = (String[])value;
StringMemberValue[] elements = new StringMemberValue[stres.length];
for(int i=0;i<stres.length;i++)
elements[i] = new StringMemberValue(stres[i],cp);
ArrayMemberValue amv = new ArrayMemberValue(cp);
amv.setValue(elements);
annotation.addMemberValue(attrName,amv);
}else
return false;
attribute.setAnnotation(annotation);
methodInfo.addAttribute(attribute);
return true;
}
return false;
}
}
3、修改日志切面类
import com.chen.annotation.JournalLog;
import com.chen.exception.CustomException;
import com.chen.staticInfos.StaticInfo;
import com.chen.utils.AnnotationUtils;
import com.chen.utils.JournalUtils;
import javassist.NotFoundException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* 日志切面
* Created by 陈梓平 on 2017/9/11.
*/
@Component
@Aspect
public class JournalAspect {
/**日志输出*/
private static final Logger logger = LoggerFactory.getLogger(JournalAspect.class);
/**日志工具类*/
@Autowired
private JournalUtils aspectJournalUtils;
/**service层切面*/
private final String POINT_CUT = "execution(* com.chen.service..*(..))";
@Pointcut(POINT_CUT)
private void pointcut(){}
/**
* 后置最终通知(目标方法只要执行完了就会执行后置通知方法)
* 日志管理
* @param joinPoint
*/
@After(value = "pointcut()")
@Transactional
public void doAfterAdvice(JoinPoint joinPoint) throws CustomException, ClassNotFoundException, NotFoundException, NoSuchMethodException {
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
int modulerType = -1;
int opreationType = -1;
modulerType = (int) AnnotationUtils.get().getAnnotationAttr(className, methodName, JournalLog.class, StaticInfo.AOP_LOG_ATTR_NAME1);
opreationType = (int) AnnotationUtils.get().getAnnotationAttr(className, methodName, JournalLog.class, StaticInfo.AOP_LOG_ATTR_NAME2);
//3.添加日志
if (modulerType!=-1&&opreationType!=-1)
//TODO 3.1 从请求获取用户id
aspectJournalUtils.addJournalInfo(modulerType,opreationType, 10086);
}
}