복붙노트

[SPRING] 인터페이스에서 주석과 일치하는 Spring AOP pointcut

SPRING

인터페이스에서 주석과 일치하는 Spring AOP pointcut

역할에 의한 액세스를 제한하기 위해 주석이 필요한 Java 6 / Spring 3에서 구현 된 서비스 클래스가 있습니다.

OperationType이라는 열거 형에서 하나 이상의 값을 값 속성으로 갖는 RequiredPermission이라는 주석을 정의했습니다.

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 패키지에 인터페이스로 게시해야합니다. . 그리고 분명히, 주석을 서비스 정의와 구현 (DRY)에 두는 것을 좋아하지 않을 것입니다.

애스펙트가 하나의 인터페이스 메소드 (예 : 트랜잭션)에 의해 실행되는 Spring AOP의 경우가 있음을 알고 있습니다. 여기에 특별한 문법이 있습니까? 아니면 상자 밖에서는 불가능한 것이 아닙니다.

추신 : 그것은 잘 작동하는 것으로 보인다 내 봄 설정을 게시하지 않았습니다. 그리고 아니요, 그것들은 원래의 클래스도 메소드 이름도 아닙니다.

조달청 : 사실, 여기에 내 봄 설정의 관련 부분입니다 :

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

<bean class="com.mycompany.aspect.MyAspect">
    <property name="userService" ref="userService" />
</bean>

해결법

  1. ==============================

    1.올바른지 이해한다면, MyService를 확장하고 주석을 달고 기본 인수를 가진 클래스의 모든 메소드를 찾는 pointcut을 원한다.

    올바른지 이해한다면, MyService를 확장하고 주석을 달고 기본 인수를 가진 클래스의 모든 메소드를 찾는 pointcut을 원한다.

    나는 당신이 다음을 대체 할 것을 제안합니다.

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

    와:

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

    조인 포인트가 MyService 클래스 또는 클래스를 확장하는 클래스와 일치하도록하려면 더하기 기호가 사용됩니다.

    도움이되기를 바랍니다!

  2. ==============================

    2.Espen, 코드는 오직 한 클래스에서만 작동합니다 :

    Espen, 코드는 오직 한 클래스에서만 작동합니다 :

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

    * com.mycompany.services. ** 패키지의 모든 서비스에 대해이 동작을 원한다면 어떻게해야합니까?

  3. ==============================

    3.이 방법으로 성공했습니다.

    이 방법으로 성공했습니다.

    http://nonrepeatable.blogspot.co.uk/2010/05/validating-service-method-parameters.html

  4. ==============================

    4.위의 제안은 도움이되지 않지만 같은 문제가 발생했습니다. 만약 내가 이것을 pointcut으로 만 가지고 있다면 :

    위의 제안은 도움이되지 않지만 같은 문제가 발생했습니다. 만약 내가 이것을 pointcut으로 만 가지고 있다면 :

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

    그런 다음 조언이 호출됩니다. 그러나, 내가 이것을 추가하면 :

       && @annotation(x.y.z.Logged)
    

    그런 다음 조언이 호출되지 않습니다. MyService 인터페이스에는, 메소드의 1 개 (살), 및 형태 선언에서도 @Logged 주석이 포함되어 있습니다.

  5. ==============================

    5.@Inherited 주석을 @RequiredPermission 주석에 추가해야합니다.

    @Inherited 주석을 @RequiredPermission 주석에 추가해야합니다.

    http://download.oracle.com/javase/6/docs/api/java/lang/annotation/Inherited.html

  6. from https://stackoverflow.com/questions/2847640/spring-aop-pointcut-that-matches-annotation-on-interface by cc-by-sa and MIT license