2015-11-13 4 views
0

Я использую AspectJ для перехвата метода с именем Request(String, String). Для этого я использую свою собственную указанную (маркерную) аннотацию. Это то, что класс выглядит следующим образом:AspectJ: методы перехвата на основе значений параметров

Class myclass { 
    public void Request(@Intercept String t, String u) { 
     // ... 
    } 
} 

аспект, который перехватывает @Intercept аннотаций:

@Aspect 
class someAspect { 
    @Intercept 
    @Around("execution(public * * (@Interceptor (*), ..))") 
    public void capture(ProceedingJoinPoint pjp) { 
     // ... 
    } 
} 

Однако мой аспект перехватывает на основе аннотированных параметров. Но я хочу, чтобы аспект перехватывал запрос метода по конкретным значениям, которые содержит параметр t.

Например, если t == "t1", метод должен быть перехвачен, в противном случае нет.

Мне было интересно, можно ли это сделать в AspectJ (в сочетании с Spring AOP).

ответ

0

На самом деле есть несколько проблем с вашим кодом (я просто переформатировать его, так что по крайней мере для чтения):

  • В именах классов Java, как правило, в верблюжьей случае, т.е. MyClass или SomeAspect вместо myclass или someAspect.
  • Имена методов в Java начинаются с символов нижнего регистра, то есть request, а не Request.
  • Вы упомянули две аннотации @Intercept и @Interceptor. С этого момента я предполагаю, что на самом деле мы имеем дело только с одним из них: @Intercept, ладно?
  • Вы также аннотируете совет вашего аспекта @Intercept, но я думаю, это не предназначено, не так ли? Это может привести к бесконечной рекурсии в другом срезе точек, если перехватывать совет перехватывает себя ...

Что касается вашего фактического вопроса, то ответ: вроде, но не статический в срезе точек (поскольку параметры определяются только во время выполнения), но динамически, также во время выполнения. У вас есть два варианта:

Вариант А: if - else в рамках консультативного кода

package de.scrum_master.app; 

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.PARAMETER) 
public @interface Intercept {} 
package de.scrum_master.app; 

public class Application { 
    public static void one(@Intercept String string) {} 
    public static void two(String string, String string2) {} 
    public static void three(@Intercept String string, int i, int j) {} 

    public static void main(String[] args) { 
     one("foo"); 
     two("foo", "bar"); 
     three("foo", 11, 22); 

     one("bingo"); 
     two("bingo", "bongo"); 
     three("bingo", 33, 44); 
    } 
} 
package de.scrum_master.aspect; 

import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.annotation.Around; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Pointcut; 

@Aspect 
public class InterceptorAspect { 
    @Pointcut("execution(public * *(@de.scrum_master.app.Intercept (*), ..)) && args(text, ..)") 
    public static void normalPointcut(String text) {} 

    @Around("normalPointcut(text)") 
    public Object capture(ProceedingJoinPoint thisJoinPoint, String text) { 
     if (text != "bingo") 
      return thisJoinPoint.proceed(); 
     System.out.println(thisJoinPoint); 
     for (Object arg : thisJoinPoint.getArgs()) 
      System.out.println(" " + arg); 
     // Do something before calling the original method 
     Object result = thisJoinPoint.proceed(); 
     // Do something after calling the original method 
     return result; 
    } 
} 

Вариант B: использование if() Pointcut

if() pointcut является статическим метод возвращает логическое значение значение, основанное на динамическом состоянии, которое вы хотите проверить. Переработан аспект будет выглядеть следующим образом:

package de.scrum_master.aspect; 

import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.annotation.Around; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Pointcut; 

@Aspect 
public class InterceptorAspect { 
    @Pointcut("if() && execution(public * *(@de.scrum_master.app.Intercept (*), ..)) && args(text, ..)") 
    public static boolean conditionalPointcut(String text) { 
     return text != "bingo"; 
    } 

    @Around("conditionalPointcut(text)") 
    public Object capture(ProceedingJoinPoint thisJoinPoint, String text) { 
     System.out.println(thisJoinPoint); 
     for (Object arg : thisJoinPoint.getArgs()) 
      System.out.println(" " + arg); 
     // Do something before calling the original method 
     Object result = thisJoinPoint.proceed(); 
     // Do something after calling the original method 
     return result; 
    } 
} 

Как вы можете видеть, динамический параметр на основе состояние переместилось в срез точек, который больше не является void метода с пустым телом, но boolean метод возвращает результат проверки параметров. Кроме того, выражение pointcut получило предварительное выражение if() &&.

консоли журнала:

Выход консоли для обоих аспектов вариантов точно такой же:

execution(void de.scrum_master.app.Application.one(String)) 
    foo 
execution(void de.scrum_master.app.Application.three(String, int, int)) 
    foo 
    11 
    22 
Смежные вопросы