如何获取Aspect中注解参数中的方法并获取方法执行的结果

问题描述

这是注释代码

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface PreVisit {
    String value();
}

控制器中的这个用法@PreVisit("@pv.hasAccess('xxxxxx')")

@PreVisit("@pv.hasAccess('xxxxxx')")
@RequestMapping(value = "getUser")
public User getUser(Integer  userId) {...some code...}

这是 pv.hasAccess('xxxxxx') 代码

@Service("pv")
public class  PageVisit{
    public boolean hasAccess(String par){        
        //return false or true;
    }
}

我的问题:
在Aspect中,如何获取注解参数中的方法获取执行结果
这是Aspect文件代码

@Aspect
@Component
public class PreVisitAspect {
    @Around("@annotation(PreVisit)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        //How do I get the result of the method execution in the annotation parameter here
        //boolean  [email protected]('xxxxxx');  pvResult=false or true
        //Do something use the pvResult
    }
}

解决方法

您可以使用第二个参数类型 PreVisit,并且您可以访问方法中的注释值。

@Aspect
@Component
public class PreVisitAspect {
    @Around("@annotation(PreVisit)")
    public Object around(ProceedingJoinPoint joinPoint,PreVisit preVisit) throws Throwable {
        //How do I get the result of the method execution in the annotation parameter here
        //boolean  [email protected]('xxxxxx');
        //Do something use the pvResult
        String value = preVisit.value();
    }
}

如果您想使用 PageVisit#hasAccess(String),请将 PageVisit 注入您的方面并调用该方法。

为此,您必须修改控制器方法,如下所示。

@PreVisit("xxxxxx")
@RequestMapping(value = "getUser")
public User getUser(Integer  userId) {...some code...}

你的方面将是。

@Aspect
@Component
public class PreVisitAspect {

    @Autowired
    private PageVisit pv;

    @Around("@annotation(PreVisit)")
    public Object around(ProceedingJoinPoint joinPoint,PreVisit preVisit) throws Throwable {
        //How do I get the result of the method execution in the annotation parameter here
        //boolean  [email protected]('xxxxxx');
        //Do something use the pvResult
        String value = preVisit.value();
        boolean hasAccess = pv.hasAccess(value);
    }
}
,

我是提问者
我已经使用 Java 反射解决了这个问题,如下所示:

@Aspect
@Component
public class PreVisitAspect {

    @Autowired
    private PageVisit pv;

    @Around("@annotation(preVisit)")
    public Object around(ProceedingJoinPoint joinPoint,PreVisit preVisit) throws Throwable {       
        String value = preVisit.value();
        //String value="@pas.hasAccess('xxxxxx')";
        if(value.startsWith("@")){
            String beanName=value.substring(value.indexOf("@")+1,value.indexOf("."));
            String methodName=value.substring(value.indexOf(".")+1,value.indexOf("("));
            String paramsStr=value.substring(value.indexOf("(")+2,value.lastIndexOf(")")-1);
            Object[] paramsArr=paramsStr.split("','");
            
            logger.info("beanName:"+beanName);
            logger.info("methodName:"+methodName);
            logger.info("paramsStr:"+paramsStr);
            
            ServletContext servletContext = request.getSession().getServletContext();
            ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
            Method method = ReflectionUtils.findMethod(appContext.getBean(beanName).getClass(),methodName,new Class[]{String.class} );
            Boolean result = (Boolean)ReflectionUtils.invokeMethod(method,appContext.getBean(beanName),paramsArr);
            logger.info(result.toString());
        }
        .....other Code.....
    }
}

tks @Karthikeyan Vaithilingam