Spring AOP Pointcut, которая соответствует аннотации на интерфейсе

StackOverflow https://stackoverflow.com/questions/2847640

Вопрос

У меня есть класс услуг, реализованный в Java 6 / Spring 3, который нуждается в аннотации для ограничения доступа ролью.

Я определил аннотацию, называемую требуемую систему, которая имеет в качестве своего значения значения одного или нескольких значений от enum под названием appertytype:

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());
    }
}

Объект параметра содержит имя пользователя, и я хочу посмотреть необходимую роль для пользователя, прежде чем разрешить доступ к способу.

Когда я положил аннотацию на метод в MyServiceImpl, все работает просто хорошо, тойтэктут соответствует и аспект пинает. Однако, я считаю, что аннотация является частью контракта на обслуживании и должна быть опубликована с помощью интерфейса в отдельном пакете API Отказ И, очевидно, я бы не хотел бы поставить аннотацию как на определение, так и в реализации (сухой).

Я знаю, что есть случаи весной AOP, где аспекты запускаются аннотациями одним интерфейсными методами (например, транзакционные). Здесь есть специальный синтаксис или просто невозможно из коробки.

PS: Я не разместил свой весенний конфиг, как кажется, работает просто хорошо. И нет, те не являются ни моим оригинальным классом, ни именами методов.

PPS: На самом деле, вот соответствующая часть моей пружинной конфигурации:

<aop:aspectj-autoproxy proxy-target-class="false" />

<bean class="com.mycompany.aspect.MyAspect">
    <property name="userService" ref="userService" />
</bean>
Это было полезно?

Решение

Если я понимаю вас правильно, вы хотите, чтобы PointCut найти все методы в классах, которые расширяют MyService и аннотируются и с предпочтительными аргументами.

Я предлагаю, чтобы вы заменили:

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

с участием:

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

Знак плюс используется, если вы хотите присоединиться к точке объединения, чтобы соответствовать классу MyService или класс, который расширяет его.

Я надеюсь, что это помогает!

Другие советы

Espen, ваш код работает только для одного класса:

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

Но что, если я хочу такое поведение для всех услуг в * com.mycompany.services. ** Пакет?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top