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

Posted

技术标签:

【中文标题】如何在Aspect的注解参数中获取方法并获取方法执行的结果【英文标题】:How do I get the method in the annotation parameter in an Aspect and get the result of the method execution 【发布时间】:2020-12-23 06:09:38 【问题描述】:

这是注释代码:

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

这个在Controller中使用@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  pvResult=@pv.hasAccess('xxxxxx');  pvResult=false or true
        //Do something use the pvResult
    

【问题讨论】:

【参考方案1】:

您可以输入第二个参数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  pvResult=@pv.hasAccess('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  pvResult=@pv.hasAccess('xxxxxx');
        //Do something use the pvResult
        String value = preVisit.value();
        boolean hasAccess = pv.hasAccess(value);
    

【讨论】:

字符串值 = preVisit.value(); value 是一个字符串,value ="@pv.hasAccess('xxxxxx')" 我希望执行 pv.hasAccess('xxxxxx') 这个结果是布尔值,是假还是真 你可以将PageVisit注入切面并调用hasAccess方法。 ``` @PreVisit("@serviceA.methodA('xxxxxx')") @PreVisit("@serviceB.methodB('xxxxxx')") @PreVisit("@serviceC.methodC( 'xxxxxx')") ```如果有三种或更多的方式,我会写三个或更多的方面【参考方案2】:

我是提问者 我已经使用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

【讨论】:

以上是关于如何在Aspect的注解参数中获取方法并获取方法执行的结果的主要内容,如果未能解决你的问题,请参考以下文章

注解+Aspect 省时省力的管理好接口日志

注解+Aspect 省时省力的管理好接口日志

Java如何获取方法参数中的名称

请问JAVA 注解中是如何获取参数注解值的?

aop配合自定义的注解使用,静态类获取request

AOP中获取自定义注解的参数值