切面与注解结合是常见的权限验证,日志记录的实现方式今天记录一下实际开发中的记录日志与注解
1.定义注解
/**
* 文档历史注解
*
*<hr>
* @author hanjidong
* @date 2020年12月2日 下午3:49:06
* @since 0.0.1
*/
@Target({ElementType.METHOD}) //作用在方法和类上
@Retention(RetentionPolicy.RUNTIME) //在运行时候有效
public @interface History {
/**
* 操作类型
*
*<hr>
* @author hanjidong
* @date 2020年12月2日 下午3:50:44
* @since 0.0.1
* @return
* String
*/
DocuHisOperateType operateType();
/**
* 类型
*
*<hr>
* @author hanjidong
* @date 2020年12月2日 下午3:50:59
* @since 0.0.1
* @return
* String
*/
HistoryFileType fileType();
}
2.注解加载方法上
/**
* 添加条目信息
* @throws FileNotFoundException
*/
@Override
@History(operateType=DocuHisOperateType.TYPE_ADD,fileType=HistoryFileType.ITEM)
public void add(Log log) throws FileNotFoundException {
System.out.println("a");
}
3.定义切面
import java.lang.reflect.Method;
import java.util.UUID;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 操作文档历史记录
*
*<hr>
* @author hanjidong
* @date 2020年11月9日 下午2:20:31
* @since 0.0.1
*/
@Aspect
@Component
public class OpreateHisAspect {
@Autowired
private LogService logService ;
/**
* 定义切入点
*
*<hr>
* @author hanjidong
* @date 2020年11月6日 下午4:59:36
* @since 0.0.1
* void
*/
@Pointcut("execution(* com.hanjidong.service.impl..*.*(..))")
public void operateDocu(){}
/**
* 前置通知:在连接点之前执行的通知
*
*<hr>
* @author hanjidong
* @date 2020年11月6日 下午4:59:29
* @since 0.0.1
* @param joinPoint
* @throws Throwable
* void
*/
@Around("operateDocu()")
public Object Around(ProceedingJoinPoint pjp) throws Throwable {
String key = UUID.randomUUID().toString();
//方法名称
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
History operateHistory = method.getAnnotation(History.class);
if(operateHistory == null){
Object proceed = pjp.proceed();
return proceed;
}
DocuHisOperateType hisOperateType = operateHistory.operateType();
IStrategy obtainHisLog = logService.obtainHisLog(hisOperateType.getCode(), pjp);
obtainHisLog.before(key,pjp);
Object proceed = pjp.proceed();
obtainHisLog.after(key, pjp);
return proceed;
}
}
4.策略模式的构建
4.1定义顶层接口
public interface IStrategy {
/**
* 根据方法名称获取操作类型
*
*<hr>
* @author hanjidong
* @date 2020年11月24日 下午7:02:36
* @since 0.0.1
* @return
* Integer
*/
abstract Integer getOperateType();
/**
* 切面前操作
*
*<hr>
* @author hanjidong
* @date 2020年11月24日 下午7:02:50
* @since 0.0.1
* @param param
* @param pjp
* @return
* List<DocumentHistoryEntity>
*/
abstract void before(String key, Object param);
/**
* 获取历史记录的数据
*
*<hr>
* @author hanjidong
* @date 2020年11月9日 下午5:45:01
* @since 0.0.1
* @param operateType
* @return
* List<DocumentHistoryEntity>
*/
abstract void after(String key,Object param);
}
定义功能实现类
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.hibernate.mapping.Array;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 添加文档历史记录
*
*<hr>
* @author hanjidong
* @date 2020年11月9日 下午8:40:42
* @since 0.0.1
*/
@Component
public class AddLog implements IStrategy{
/**
* 添加
*/
@Override
public void after(String key, Object param) {
if(!(param instanceof ProceedingJoinPoint)){
return;
}
//切点
ProceedingJoinPoint point = (ProceedingJoinPoint)param;
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
History operateHistory = method.getAnnotation(History.class);
Object[] args = point.getArgs();
System.out.println("==AddLog ==after");
}
/**
* 执行前操作
*/
@Override
public void before(String key, Object param) {
// TODO Auto-generated method stub
System.out.println("==AddLog ==before");
}
/**
* 执行后操作
*/
@Override
public Integer getOperateType() {
return DocuHisOperateType.TYPE_ADD.getCode();
}
}
调用函数
import java.util.Objects;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
/**
* 路由
*
*<hr>
* @author hanjidong
* @date 2020年11月24日 下午7:39:48
* @since 0.0.1
*/
@Component
public class LogService {
@Resource
private IStrategy[] strategys;
public IStrategy route(Integer operateType) {
for (IStrategy strategy : strategys) {
if (Objects.equals(operateType, strategy.getOperateType())) {
return strategy;
}
}
throw new IllegalArgumentException("属性类型,不符合规范");
}
public IStrategy obtainHisLog(Integer operateType, Object param) {
IStrategy strategy = route(operateType);
if (strategy == null) {
throw new IllegalArgumentException("属性类型,不符合规范");
}
return strategy;
}
}