1、Aop切面注解:
1.1@Aspect注解将一个Java类定义为切面类;
1.2@Pointcut定义一个切入点,可以是一个表达式,例:package下的所有函数,也可是一个注解;
根据切入点的不同位置切入内容
1.3@Before在切入点开始处切入内容;
1.4@After在切入点的结尾处切入内容;
1.5@AfterReturning在切入点return内容之后切入内容
1.6@Around在切入点前后切入内容,自己可以控制何时执行切入点的自身内容;
1.7@AfterThrowing用来处理切入内容部分抛出异常之后的逻辑;
注意:@AfterThrowing不执行的原因是没有在异常的方法里抛出异常,就不会执行这个异常通知,解决办法在方法里加“throw new RuntimException()”
2、Aop日志管理前置、后置消息组合使用(不能决定是否调用目标目标方法)
@Aspect//没有此注解这个类不起作用
@Component
public class LogInterceptor {
@Pointcut("execution(* com.路径..*.*(..))")
public void appliceException() {
System.out.println("3");
}
@Pointcut("execution(* com.路径.service.impl.*.*(..))")
public void domainException() {
System.out.println("4");
}
// 这里注解里面的值为上面的方法名
@Before("appliceException()||domainException()")
public void doBefore(JoinPoint joinPoint) {
System.out.println("前置通知 : " + joinPoint.getSignature().toLongString());
}
/**@AfterThrowing捕获时一定要在异常中抛出
* 如用户登录的信息可从joinPoint获取,做相应的处理
*/
@AfterThrowing(value = "appliceException()||domainException()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
System.out.println(
"@AfterThrowing :" + joinPoint.getSignature().toLongString() + "---------开始" + e.getMessage() + "结束");
}
@After(value = "appliceException()||domainException()")
public void doAfter(JoinPoint joinPoint) {
System.out.println("最终通知" + joinPoint.getSignature().toLongString());
}
}
3、Aop日志管理环绕通知(是否调用目标方法环绕可决定)
3.1实现类
/**
* 环绕通知将决定要不要执行连接点
*
*/
@Around(value = "point()")
public Object myAroundAdivice(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取方法参数值数组
Object[] args = joinPoint.getArgs();
// 得到其方法签名
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
// 获取方法参数类型数组
Class[] paramTypeArray = methodSignature.getParameterTypes();
logger.info("请求参数为{}", args);
// 动态修改其参数
// 注意,如果调用joinPoint.proceed()方法,则修改的参数值不会生效,必须调用joinPoint.proceed(Object[] args)
Object result = joinPoint.proceed(args);
logger.info("响应结果为{}", result);
// 如果这里不返回result,则目标对象实际返回值会被置为null
System.out.println("环绕通知,执行代码后");
return result;
}
@Pointcut("@annotation(com.路径.AopAround)") // 表示所有带有AssertOK的注解
public void point() {
System.out.println("自定义注解");
}
3.2自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AopAround {
String isLogin() default "false";
}
3.3 pom.xml引入
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.0</version>
</dependency>
3.4在需要拦截的地方加入自动一注解
小结:①目标方法的调用由环绕通知决定,可以决定是否调用目标方法,而前置、后置通知不能决定
②环绕通知可以控制返回对象,可以返回一个与目标对象完全不同的返回值;后置办不到,因为是目标方法返回值后调用
----------------------------------------------个人见解,