当前位置: 首页 > 知识库问答 >
问题:

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

聂和宜
2023-03-14

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

建议:

@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下?

共有2个答案

慕嘉运
2023-03-14

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

我假设你在注释中打了一个错字,你可能指的是@Aspect而不是@建议

我的建议是尝试这些:

a、 分为命名切入点和要应用于切入点的建议:

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

b、 可能是由于表达式或表达式导致了问题-请尝试保留其中一个并删除另一个,然后看看哪个组合有效。

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){}
赵俊远
2023-03-14

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

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

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

当我运行updatemanageimpl时。main,我看到了如下输出,正如预期的那样:

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

免责声明:我不是Spring,我只是用普通的AspectJ测试了这个,而不是Spring AOP。

 类似资料:
  • 我正在使用注释处理来生成一些类...我有两个模块,处理器本身和使用它的“客户端”模块。我想通过客户端向处理器传递一个参数,我可以这样做 如何在处理器端检索此参数?

  • 问题内容: 我想将maven命令行参数传递给POM.xml,以便我可以将这些值用于构建目的中的其他目的。 问题答案: 经过一些搜索,我们可以以不同的方式提供参数,我发现一些有用的 … 实际上,在我的应用程序中,我需要保存并提供SVN版本作为参数,因此我已经按照上述方法实现了。 在运行构建时,我们需要为这些参数提供值,如下所示。 我在这里供应 它为我工作。谢谢

  • 问题内容: 我正在A中使用RUN指令安装rpm 但是,我想将值“ 2.3”作为参数传递。我的RUN指令应类似于: 哪里 问题答案: 您正在寻找和指导。这些是Docker 1.9中的新功能。查看https://docs.docker.com/engine/reference/builder/#arg。这将允许您添加到,然后使用构建。

  • 问题内容: 这似乎是一个愚蠢的问题,但是我是这个话题的新手。我正在致力于关于节点js的承诺。我想将参数传递给Promise函数。但是我不知道。 而功能类似于 问题答案: 将Promise包裹在一个函数中,否则它将立即开始工作。另外,您可以将参数传递给函数: 然后,使用它: ES6: 用:

  • 问题内容: 我想将登录用户单击的sa 列表中的传递给twitter bootstrap 。我正在与 angularjs* 一起使用 grails ,其中数据是通过 angularjs 呈现的。 *** 组态 我的grails视图页面是 我的是 所以,我怎么能传递到? 问题答案: 我尝试如下。 我在 鼓励 按钮上打电话给angularjs控制器, 我设置的从angularjs控制器。 我提供了一个p

  • 问题内容: 我正在使用Go内置的http服务器,并拍拍来响应一些URL: 我需要向该处理函数传递一个额外的参数-一个接口。 如何向处理程序函数发送额外的参数? 问题答案: 通过使用闭包,您应该能够做您想做的事情。 更改为以下内容(未测试): 然后对