代码之家  ›  专栏  ›  技术社区  ›  Sean Patrick Floyd

与接口上的注释匹配的Spring AOP切入点

  •  27
  • Sean Patrick Floyd  · 技术社区  · 16 年前

    我在Java6/Spring3中实现了一个服务类,它需要一个注释来限制角色的访问。

    我定义了一个名为RequiredPermission的批注,它的值属性是一个或多个来自名为OperationType的枚举的值:

    public @interface RequiredPermission {
    
    /**
     * One or more {@link OperationType}s that map to the permissions required
     * to execute this method.
     * 
     * @return
     */
    OperationType[] value();}
    
    public enum OperationType {
          TYPE1,
          TYPE2;
    }
    
    package com.mycompany.myservice;
    public interface MyService{
       @RequiredPermission(OperationType.TYPE1)
       void myMethod( MyParameterObject obj );
    }
    
    package com.mycompany.myserviceimpl;
    public class MyServiceImpl implements MyService{
       public myMethod( MyParameterObject obj ){
           // do stuff here
       }
    }
    

    我还有以下方面的定义:

    /**
     * Security advice around methods that are annotated with
     * {@link RequiredPermission}.
     * 
     * @param pjp
     * @param param
     * @param requiredPermission
     * @return
     * @throws Throwable
     */
    @Around(value = "execution(public *"
            + " com.mycompany.myserviceimpl.*(..))"
            + " && args(param)" + // parameter object
            " && @annotation( requiredPermission )" // permission annotation
    
    , argNames = "param,requiredPermission")
    public Object processRequest(final ProceedingJoinPoint pjp,
            final MyParameterObject param,
            final RequiredPermission requiredPermission) throws Throwable {
        if(userService.userHasRoles(param.getUsername(),requiredPermission.values()){
            return pjp.proceed();
        }else{
            throw new SorryButYouAreNotAllowedToDoThatException(
                param.getUsername(),requiredPermission.value());
        }
    }
    

    parameter对象包含用户名,我想在允许访问该方法之前查找该用户所需的角色。

    当我在MyServiceImpl的方法上添加注释时,一切正常,切入点匹配,方面开始工作。但是,我认为注释是服务契约的一部分,应该在单独的API包中与接口一起发布。显然,我不想将注释放在服务定义和实现(DRY)上。

    我知道在springaop中,有些方面是由一个接口方法(例如事务)触发的。这里有没有一个特殊的语法,或者说它是完全不可能开箱即用的。

    PS:我还没有发布我的spring配置,因为它似乎工作得很好。不,这些既不是我原来的类名,也不是方法名。

    <aop:aspectj-autoproxy proxy-target-class="false" />
    
    <bean class="com.mycompany.aspect.MyAspect">
        <property name="userService" ref="userService" />
    </bean>
    
    5 回复  |  直到 8 年前
        1
  •  35
  •   Espen    16 年前

    如果我的理解是正确的,那么您需要一个切入点来查找扩展MyService的类中的所有方法,并且带有注释和首选参数。

    我建议你替换:

    execution(public * com.mycompany.myserviceimpl.*(..))
    

    使用:

    execution(public * com.mycompany.myservice.MyService+.*(..))
    

    如果希望joinpoint与MyService类或扩展它的类匹配,则使用加号。

    希望有帮助!

        2
  •  6
  •   pkmk    16 年前

    execution(public * com.mycompany.myservice.MyService+.*(..))