如何将参数传递给带有注释参数的Spring AOP建议?

我正在使用Spring 3.1.2.RELEASE与cglib加载时编织,我想获得建议,使用具有自定义注释和注释参数的方法。

建议:

@Aspect
public class MyAdvice
{
   @Around("execution(@com.mycompany.locking.Lock * *(@com.mycompany.locking.LockVal(*), ..)) " +
   "&& args(batch) && @args(propertyToLock)"
   public Object lockAndProceed(ProceedingJoinPoint pjp, Object batch, LockVal propertyToLock) throws Throwable { 
        //Do stuff.... 
        pjp.proceed();
   }
}

这是我正在测试的课程:

public interface UpdateManager
{
   public void processUpdate(MyBatchObject batch);
}


public class UpdateManagerImpl implements UpdateManager
{
   @Lock
   public void processUpdate(@LockVal("lockValue") MyBatchObject batch)
   {
      //Do stuff...
   }
}

问题是我无法获得执行建议。 如果我删除了切入点中的@args和args条件,那么通知会触发,但是我必须深入研究ProceedingJoinPoint以获取我需要的参数。

为什么不建议解雇? 我做错什么了吗?

编辑 :以下切入点可以作为Spring的独立程序使用:

@Aspect
public class MyAdvice
{
   @Around("execution(@com.mycompany.locking.Lock * *(@com.mycompany.locking.LockVal(*), ..)) " +
   "&& args(batch)"
   public Object lockAndProceed(ProceedingJoinPoint pjp, Object batch) throws Throwable { 
        //Do stuff.... 
        pjp.proceed();
   }
}

但是,它不能在JBoss 6下使用加载时编织工作。 那么我想我的问题应该是,为什么它会作为一个独立的程序运行,但不是在JBoss 6下运行?


更新:我忘了提及@args()并不是要匹配参数的注释,而是一个参数类型的注释,这不是你想要的,因此我在这里不使用它。


您不能通过args()绑定参数的注释,只能绑定参数本身。 这意味着您只能通过反射访问参数的注释。 您需要确定方法签名,从中创建一个Method对象,然后迭代方法参数的注释。 这是一个完整的代码示例:

package com.mycompany.locking;

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.METHOD)
public @interface Lock {}
package com.mycompany.locking;

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 LockVal {
    String value() default "";
}
package com.mycompany;

public class MyBatchObject {}
package com.mycompany;

public interface UpdateManager {
    public void processUpdate(MyBatchObject batch);
}
package com.mycompany;

import com.mycompany.locking.Lock;
import com.mycompany.locking.LockVal;

public class UpdateManagerImpl implements UpdateManager {
    @Lock
    @Override
    public void processUpdate(@LockVal("lockValue") MyBatchObject batch) {
        System.out.println("Processing update");
    }

    public static void main(String[] args) {
        UpdateManager updateManager =  new UpdateManagerImpl();
        updateManager.processUpdate(new MyBatchObject());
    }
}
package com.mycompany.aop;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

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

import com.mycompany.MyBatchObject;
import com.mycompany.locking.LockVal;

@Aspect
public class MyAspect {
    @Pointcut("execution(@com.mycompany.locking.Lock * *(@com.mycompany.locking.LockVal (*), ..)) && args(batch)")
    public void lockedMethod(MyBatchObject batch) {}

    @Around("lockedMethod(batch)")
    public Object lockAndProceed(ProceedingJoinPoint pjp, MyBatchObject batch) throws Throwable {
        System.out.println(pjp);
        System.out.println(batch);
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        Class<?> clazz = methodSignature.getDeclaringType();
        Method method = clazz.getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes());
        LockVal propertyToLock;
        for (Annotation ann : method.getParameterAnnotations()[0]) {
            if(LockVal.class.isInstance(ann)) {
                propertyToLock = (LockVal) ann;
                System.out.println(propertyToLock.value());
            }
        }
        return pjp.proceed();
    }
}

当我运行UpdateManagerImpl.main ,我看到以下输出,就像预期的那样:

execution(void com.mycompany.UpdateManagerImpl.processUpdate(MyBatchObject))
com.mycompany.MyBatchObject@86f241
lockValue
Processing update

免责声明:我不是Spring的家伙,我只是用普通的AspectJ而不是Spring AOP来测试它。


这不是一个解决方案,但应该让你更进一步:

我假设你在注释中犯了一个错字,你可能是指@Aspect而不是@Advice

我的建议是尝试这些:

一个。 将其分解为命名的切入点和要在切入点上应用的建议:

@PointCut("execution(@com.mycompany.locking.Lock * *(@com.mycompany.locking.LockVal(*), ..)) && args(batch) && @args(propertyToLock)")
public void mypointcut(Object batch, LockVal propertyToLock){}

@Around("mypointcut(batch, propertyToLock)"
public Object lockAndProceed(ProceedingJoinPoint pjp, Object batch, LockVal propertyToLock) throws Throwable { 
    //Do stuff.... 
    pjp.proceed();
}   

湾 可能是args表达式或@args表达式导致了这个问题 - 尝试保留一个并删除其他的并查看哪个组合起作用。

C。 如果这不能缩小范围,那么还有一个选项可能是显式添加一个argNames表达式,这可能是参数名称正在被清除,并且不会在运行时按名称进行匹配:

 @PointCut("execution(@com.mycompany.locking.Lock * *(@com.mycompany.locking.LockVal(*), ..)) && args(batch) && @args(propertyToLock) && argNames="batch,test1,test2")
public void mypointcut(Object batch, LockVal propertyToLock){}
链接地址: http://www.djcxy.com/p/13523.html

上一篇: How do I pass arguments to Spring AOP advice with annotated parameters?

下一篇: How to print a class or objects of class using print()?