SpringAop日志管理实现方式

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在需要拦截的地方加入自动一注解

小结:①目标方法的调用由环绕通知决定,可以决定是否调用目标方法,而前置、后置通知不能决定

②环绕通知可以控制返回对象,可以返回一个与目标对象完全不同的返回值;后置办不到,因为是目标方法返回值后调用

----------------------------------------------个人见解,

发布了5 篇原创文章 · 获赞 0 · 访问量 238

猜你喜欢

转载自blog.csdn.net/qq_31129841/article/details/105427543