【问题标题】:How do I get the method in the annotation parameter in an Aspect and get the result of the method execution如何在Aspect的注解参数中获取方法并获取方法执行的结果
【发布时间】: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
    }
}

【问题讨论】:

    标签: java annotations aspect


    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-10
      • 2017-06-05
      • 2017-11-19
      • 2012-02-05
      • 2015-05-26
      • 2020-01-26
      • 2012-01-16
      相关资源
      最近更新 更多