- aop是面向切面编程,在不改变其方法的内部逻辑来增强一个方法的执行
aop的几种通知: 前置通知、后置通知、异常通知、环绕通知
使用aop的方法:自定义一个注解类来标记方法,或者是直接监控方法
下面使用了前置通知和后置通知
自定义注解
/**
* 自定义操作日志记录注解
*
* @author Ghl
*
*/
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/**
* 模块
*/
public String title() default "";
/**
* 类型操作:比如 0:是对学生的操作 1:是课程和批次操作 ...
*
*/
public String flag() default "";
/**
* 操作的类型 比如 1:增加 2:修改 3:删除
*
*/
public int openType() default 0;
}
标记方法
@Log(title="自考订单关闭操作",openType = 2,flag = "12")
public int closeOrder(String id) {
return gxOrderMapper.closeOrder(id);
}
监控标记方法
/**
* @param joinPoint 切点 可以获取到数据参数
*/
@AfterReturning(pointcut = "logPointCut()")
public void doAfterReturning(JoinPoint joinPoint) {
//处理日志操作的逻辑处理
handleLog(joinPoint);
}
JoinPoint 代理了被监控方法中的参数,解析代理对象
public void getInFo(final JoinPoint joinPoint){
//获取Log中的标记
Log annotationLog = getAnnotationLog(joinPoint);
//获取方法参数
Object[] args = joinPoint.getArgs();}
/**
* 是否存在注解,如果存在就获取
*/
private Log getAnnotationLog(JoinPoint joinPoint) throws Exception {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
return method.getAnnotation(Log.class);
}
return null;
}
前置通知(单独监控某个方法,删除操作使用的前置通知)
//单独监控删除批次日志的信息
@Pointcut("execution(* com.gx.manager.biz.impl.GxPeriodBizImpl.deteleGxPeriod(..))")
public void delGxPeriod(){}
@Before("delGxPeriod()")
public void delGxPeriodLog(JoinPoint joinPoint){
}
环绕通知
环绕通知的注解 @Around("LogAspect()") 。LogAspect()监控方法的切点
被监控的方法
@SysLog(module = "环绕通知设置", methods = "学习环绕通知")
public void show(String id){
System.out.println("我是执行中3。。。。。"+id);
}
监控类
@Aspect
@Component
public class SysLogAop {
//统一监控SysLog注解的方法切点
@Pointcut("@annotation(org.demo.logger.annotation.SysLog)")
public void LogAspect() {
}
@Around("LogAspect()")
public Object doAround(ProceedingJoinPoint point) {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes)ra;
HttpServletRequest request = sra.getRequest();
//如果中间执行的方法有返回值就就接收返回值
Object result = null;
try {
System.out.println("我是环绕通知的前置通知。。。。。。。。。1");
//中间执行的是目标方法
result = point.proceed();
System.out.println("我是环绕通知的后置通知。。。。。。。。。3");
} catch (Throwable e) {
logger.error("异常信息:{}", e.getMessage());
throw new RuntimeException(e);
}
return result;
}
}