zoukankan      html  css  js  c++  java
  • getAnnotation为null的坑

    在写一个基于SpringAOP的权限控制的。

    自己定义了一个注解,然后逻辑代码需要通过获取自定义注解的一个属性来进行权限控制。

    下面简单上一下关键代码:

    自定义注解:

    @Documented  //有关java doc的注解
    @Retention(RetentionPolicy.RUNTIME)  //保留时间,这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用.
    @Target(ElementType.METHOD) //针对方法
    public @interface AuthorizationNeed {
        
        //自定义注解的属性,default是设置默认值
        //String operation() default "addAndUpdate";    
        String operation();    //这个属性用来知道这是什么操作,不同操作的写法不一样
    
    }

    切点:

    /**
         * 定义个个切入点
         * 所有有这个注解的方法
         */
        @Pointcut("@annotation(com.inforPoint.util.AuthorizationNeed)")
        private void needAuthorizationPoint() {}

    然后在切面中有个@Around的环绕加强,需要在里面获取注解AuthorizationNeed的属性operation的值。  在网上找了个方法,这是一开始的写法:

    //下面这句代码是获得那个自定义的注解的对象
    AuthorizationNeed authorizationNeed = ( (MethodSignature)proceedingJoinPoint.getSignature() ).getMethod().getAnnotation(AuthorizationNeed.class);
    
            
    String operation = authorizationNeed.operation();  //用注解的时候有指明是什么操作

    但却在运行的时候一直反应  这个authorizationNeed是null。

    网上有说可能是注解的定义问题,要

    @Retention(RetentionPolicy.RUNTIME)

    但显然不是这个错。

    后面百度了很久之后,原来是这个aop拦截的是ServiceImpl的一个方法,然后这个ServiceImpl又启动了事务管理,而事务管理又是基于AOP的。

    也就是说,这个权限的@Around的切面拦截的是个代理对象的方法,而代理对象的方法是不会把原来父类中的方法的注解加上去的,所以这里这个注解的对象为null。后面网上找到了一个可以解决问题的代码:

    /**
         * 这个方法帮忙拿出注解中的operation属性
         * 因为有拦截serviceImpl的方法,而这些方法又加了事务管理,也就是这里也有aop,这些已经是代理类,用之前的写法获得的是代理类的方法,而这些
         * 方法是特么不会把父类中的方法的注解加上去的!!!
         * @param proceedingJoinPoint
         */
        private String getOperationOfTheAnnotation(ProceedingJoinPoint proceedingJoinPoint) throws Exception {
            
            Signature signature =  proceedingJoinPoint.getSignature();//方法签名
            Method method = ( (MethodSignature)signature ).getMethod();
            
            //这个方法才是目标对象上有注解的方法
            Method realMethod = proceedingJoinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), method.getParameterTypes());
            
                    
            AuthorizationNeed authorizationNeed = realMethod.getAnnotation(AuthorizationNeed.class);
            
            return authorizationNeed.operation();
                    
    
        }

    参考博客:

    https://www.cnblogs.com/qiumingcheng/p/5923928.html    贴近作者实际地讲这个问题

    https://blog.csdn.net/frightingforambition/article/details/78842306

  • 相关阅读:
    Java设计模式之原型模式
    Java设计模式之单例模式
    Java设计模式之抽象工厂模式
    Java设计模式之工厂方法模式
    redis常用配置参数详解
    Maven版本的ssm框架项目常见依赖pom.xml
    Maven中setting.xml配置Demo
    Linux中安装jdk
    Linux中查看jdk安装目录、Linux卸载jdk、rpm命令、rm命令参数
    Hibernate主键生成策略
  • 原文地址:https://www.cnblogs.com/wangshen31/p/9498731.html
Copyright © 2011-2022 走看看