aop介绍
1.六种通知方式
- 环绕通知:在目标方法执行前和执行后实施增强,可用于日志记录,事务处理等
- 前置通知:在目标方法执行前实施增强,可用于权限管控等
- 后置返回通知:在目标方法成功执行后实施增强,可用于关闭流,删除临时文件等
- 后置通知:在目标方法执行后实施增强(无论方法是否发生异常都执行),可用于释放资源
- 异常通知:在目标方法抛出异常时实施增强,可用于处理异常,记录日志等
- 引入通知:在目标类中添加一些方法和属性,用于修改目标类
2.aspectj相关注解
@aspect:用于定义一个切面,注解在切面类上@pointcut:用于定义切点表达式,在使用时,需要定义一个切入点方法,该方法返回值为void,且方法体为空的普通方法@before:用于定义前置通知,通常为其指定value属性,该值可以是已有切入点,也可以定义切点表达式@afterreturning:用于定义后置返回通知,通常为其指定value属性,该值可以是已有切入点,也可以定义切点表达式@around:用于定义环绕通知,通常为其指定value属性,该值可以是已有切入点,也可以定义切点表达式afterthrowing:用于定义异常通知,通常为其指定value属性,该值可以是已有切入点,也可以定义切点表达式。另外还有一个 throwing属性用于访问目标方法抛出的异常,该属性值与异常通知方法中同名的形参一致after:用于定义后置最终通知,通常为其指定value属性,该值可以是已有切入点,也可以定义切点表达式
定义切入点的两种方式
1.注解
//定义注解
@target(elementtype.method)
@retention(retentionpolicy.runtime)
@documented
public @interface safetyharness {
string defaultvalue() default "";
}
//切入点
@pointcut("@annotation(com.xx.xx.xx.web.annotation.safetyharness)")
public void efficacyparameters(){
}2.表达式
//该controller所有方法,可以直接指定
/*
execution():表达式主体
第一个 * 表示返回类型,使用*表示所有类型,该 * 与包名之间有一个空格
第二个 * 表示类名
第三个 * 表示方法名
..表示任意参数
*/
@pointcut("value = "execution(* com.xx.xx.xx.web.controller.*.* (..)))")
public void efficacyparameters(){
}常用两种通知获取参数
1.@before
@before("efficacyparameters()")
public void beforeefficacyparameters(joinpoint joinpoint){
//获取请求参数
servletrequestattributes attributes = (servletrequestattributes) requestcontextholder.getrequestattributes();
httpservletrequest request = objects.requirenonnull(attributes).getrequest();
map<string, string[]> parametermap = request.getparametermap();
//通过参数名获取
object ext1 = parametermap.get("ext1");
object ext2 = parametermap.get("ext2");
}2.@around
@around("efficacyparameters()")
public t beforeefficacyparameters(proceedingjoinpoint joinpoint){
//接口返回结果,该结果可在业务前或业务后执行
object proceed = joinpoint.proceed();
object[] obj = joinpoint.getargs();
if (obj == null || obj.length == 0) {
return t;
}
//获取请求参数
map<string, object> fieldsname = getfieldsname(joinpoint);
object ext1 = fieldsname.get("ext1");
//post请求强转
safetyauditpagevo ext2 = (safetyauditpagevo) fieldsname.get("ext");
//修改请求参数
safetyauditpagevo vo = (safetyauditpagevo) obj[0];
vo.setxxxx("xxxxxx");
obj[0] = vo;
return joinpoint.proceed(obj);
}
private static map<string, object> getfieldsname(proceedingjoinpoint joinpoint) {
object[] args = joinpoint.getargs();
parameternamediscoverer pnd = new defaultparameternamediscoverer();
methodsignature signature = (methodsignature) joinpoint.getsignature();
method method = signature.getmethod();
string[] parameternames = pnd.getparameternames(method);
map<string, object> parammap = new hashmap<>(32);
for (int i = 0; i < parameternames.length; i++) {
parammap.put(parameternames[i], args[i]);
}
return parammap;
}总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论