Android开发

AspectJ中的JoinPoint方法概要

2019-04-22  本文已影响0人  huapro

https://www.cnblogs.com/mosmith/p/6785708.html
注解@EnableAspectJAutoProxy。从下面EnableAspectJAutoProxy的定义可以看到,注解导入了AspectJAutoProxyRegistrar配置类。
AspectJAutoProxyRegistrar主要在BeanDefinitionRegistry里面注册了AnnotationAwareAspectJAutoProxyCreator。从AnnotationAwareAspectJAutoProxyCreator的继承结构可以看出AnnotationAwareAspectJAutoProxyCreator是一个BeanPostProcessor,类似EnableWebMvc,这个类用来整合AspectJ和Spring的IOC容器。
我们跳到继承结构上与AspectJ相关的annotation处理的相关方法,这个方法重写了父类的findCandidateadvisors(父类主要处理xml方式配置的advisor,这里添加了对注解声明的Adivisor的扫描,我们跳到BeanFactoryAspectJAdvisorsBuilder里面的buildAspectJAdvisors方法,从这个方法可以看到它从BeanFactory,也就是我们的Context里面取出所有的Bean,然后检查这个Bean是否有@Aspect注解,如果有的话则构建Advisor元数据,这里不直接构建Advisor实例,因为它由Spring IOC容器来管理。

AspectJ中的切入点匹配的执行点称作连接的(Join Point),在通知方法中可以声明一个JoinPoint类型的参数。通过JoinPoint可以访问连接点的细节。下面简要介绍JponPoint的方法:

1.java.lang.Object[] getArgs():获取连接点方法运行时的入参列表;
2.Signature getSignature() :获取连接点的方法签名对象;
3.java.lang.Object getTarget() :获取连接点所在的目标对象;
4.java.lang.Object getThis() :获取代理对象本身;

ProceedingJoinPoint继承JoinPoint子接口,它新增了两个用于执行连接点方法的方法:

5.java.lang.Object proceed() throws java.lang.Throwable:通过反射执行目标对象的连接点处的方法;
6.java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通过反射执行目标对象连接点处的方法,不过使用新的参数替换原来的参数。

package com.keke.userService.config.exception;


import com.keke.common.util.JwtTokenUtil;
import com.keke.common.util.ResultBase;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 
 */
@Aspect
@Component
public class HttpAspect {
    private final static Logger LOGGER = LoggerFactory.getLogger(HttpAspect.class);
    @Autowired
    private ExceptionHandle exceptionHandle;

    // 对该注解的任何方法都切入
    // execution1:   移除LoginController类 的所有方法(任意参数)
    // execution2: controller 包下的所有子包所有类的所有方法(任意参数)
    @Pointcut("!execution(* com.keke.userService.controller.LoginController.*(..))  &&  execution(* com.keke.userService.controller..*.*(..)) ")
    public void log() {

    }

    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        //打印请求信息
        printRequestInfo(joinPoint);
    }


    //打印请求信息
    private void printRequestInfo(JoinPoint joinPoint){

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
//      String token= request.getHeader("kexin_token");
//
//      JwtTokenUtil.verifyToken(token);

        // url
        LOGGER.info("url={}", request.getRequestURL());
        // method
        LOGGER.info("method={}", request.getMethod());
        // ip
        LOGGER.info("id={}", request.getRemoteAddr());
        // class_method
        LOGGER.info("class_method={}",
                joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());
        // args[]
        LOGGER.info("args={}", joinPoint.getArgs());



    }



    @Around("log()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        ResultBase result = null;
        try {

        } catch (Exception e) {
            return exceptionHandle.defaultErrorHandler(e);
        }
        if (result == null) {
            return proceedingJoinPoint.proceed();
        } else {
            return result;
        }
    }

    @AfterReturning(pointcut = "log()", returning = "object") // 打印输出结果
    public void doAfterReturing(Object object) {
        LOGGER.info("response={}", object.toString());
    }
}

上一篇下一篇

猜你喜欢

热点阅读