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

具有相同名称但不同参数的两个方法的两个切入点

柴意智
2023-03-14
/** Interface of the class to observe. */
public interface PersistenceService {

    public Serializable save(Serializable serializable);

    public List<Serializable> save(List<Serializable> list)
}

/** Actual class to observe. */
@Service
public class PersistenceService {

    @Autowired
    private SomeJpaRepository rep;

    public Serializable save(Serializable serializable) {
        return rep.save(serializable);
    }

    public List<Serializable> save(List<Serializable> list) {
        return rep.save(list);
    }
}
/** The Aspect. */
@Aspect
@Component
public class PersistenceService {

    /** A org.slf4j.Logger (using logback). */
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /** Pointcut to define the classes to observe. */
    @Pointcut("within(de.mypckg.myproject.persistence.*.*)")
    public void inPersistanceLayer() {}

    /** Pointcut for the first save-method. */
    @Pointcut("execution(public * save(..)) && args(serializable)")
    public void saveOperation(Serializable serializable) {}

    /** Pointcut for the first save-method. */
    @Pointcut("execution(public * save(..)) && args(list)")
    public void saveOperation(List<Serializable> list) {}

    /** Method for the first save-method. */
    @Around("inPersistanceLayer() && saveOperation(serializable)")
    public List<Serializable> logSave(ProceedingJoinPoint joinPoint, Serializable serializable) throws Throwable {

        // log some stuff
        Object saved = joinPoint.proceed();
        // log somemore stuff
    }

    /** Method for the second save-method. */
    @Around("inPersistanceLayer() && saveOperation(list)")
    public List<Serializable> logSave(ProceedingJoinPoint joinPoint, List<Serializable> list) throws Throwable {

        // log some stuff
        Object saved = joinPoint.proceed();
        // log somemore stuff
    }
}
java.lang.IllegalArgumentException: warning no match for this type name: list [Xlint:invalidAbsoluteTypeName]

我改变了切入点的顺序,它总是排在第二位。关于如何解决这个问题有什么想法吗?

更新
一旦我发布了这个问题,我就有了一个想法。我这样更改了切入点:

/** The Aspect. */
@Aspect
@Component
public class PersistenceService {

    /** A org.slf4j.Logger (using logback). */
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /** Pointcut to define the classes to observe. */
    @Pointcut("within(de.mypckg.myproject.persistence.*.*)")
    public void inPersistanceLayer() {}

    /** Pointcut for the save-method. */
    @Pointcut("execution(public * save(..))")
    public void saveOperation() {}

    /** Pointcut for the serializable argument. */
    @Pointcut("args(serializable)")
    public void serializableArgument(Serializable serializable) {}

    /** Pointcut for the list argument. */
    @Pointcut("args(list)")
    public void listArgument(List<Serializable> list) {}

    /** Method for the first save-method. */
    @Around("inPersistanceLayer() && saveOperation() && serializableArgument(serializable)")
    public Object logSave(ProceedingJoinPoint joinPoint, Serializable serializable) throws Throwable {

        // log some stuff
        Object saved = joinPoint.proceed();
        // log somemore stuff
        return saved;
    }

    /** Method for the second save-method. */
    @Around("inPersistanceLayer() && saveOperation(list) && listArgument(list)")
    public Object logSave(ProceedingJoinPoint joinPoint, List<Serializable> list) throws Throwable {

        // log some stuff
        Object saved = joinPoint.proceed();
        // log somemore stuff
        return saved;
    }
}

现在异常消失了,但仍然有一个小问题(我想这个问题更容易解决):因为ArrayList实现了可序列化,所以至少在我使用ArrayList的测试用例中,两个切入点都被执行了。
我将对此进行研究,并发布我的发现,但也感谢您的帮助;)

我将代码改为只使用一个切入点和一个方法,并像kriegaex建议的那样使用instanceof检查。

/** The Aspect. */
@Aspect
@Component
public class PersistenceService {

    /** A org.slf4j.Logger (using logback). */
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /** Pointcut to define the classes to observe. */
    @Pointcut("within(de.mypckg.myproject.persistence.*.*)")
    public void inPersistanceLayer() {}

    /** Pointcut for the save-method. */
    @Pointcut("execution(public * save(*)) && args(serializable)")
    public void saveOperation(Serializable serializable) {}

    /** Method for the first save-method. */
    @Around("inPersistanceLayer() && saveOperation() && serializableArgument(serializable)")
    public Serializable logSave(ProceedingJoinPoint joinPoint, Serializable serializable) throws Throwable {

        // log some stuff
        Serializable saved = (Serializable) joinPoint.proceed();

        if (saved instanceof List<?>) {
            List<?> savedList = (List<?>) saved;
            // log somemore stuff with a List
        } else {
            // log somemore stuff
        }
        return saved;
    }
}

我仍然想知道为什么它没有反过来工作。

共有1个答案

濮书
2023-03-14

以下为您提供两种选择:

应用程序类

package de.scrum_master.aspectj.sample;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class TestApp {
    public static void main(String[] args) {
        save(new HashSet<String>());
        List<Serializable> arg = new ArrayList<Serializable>();
        save(arg);
    }
    static Serializable save(Serializable arg) { return arg; }
    static List<Serializable> save(List<Serializable> arg) { return arg; }
}

方面

package de.scrum_master.aspectj.sample;

import java.io.Serializable;
import java.util.List;

public aspect TestAspect {
    pointcut saveOperation(Object arg) : execution(* save(*)) && args(arg);
    pointcut serializableArgument(Serializable serializable) : execution(* save(Serializable)) && args(serializable);
    pointcut listArgument(List<Serializable> list) : execution(* save(List<Serializable>)) && args(list);

    Object around(Object arg) : saveOperation(arg) {
        if (arg instanceof List)
            System.out.println("Global advice   [List]:         " + thisJoinPointStaticPart.getSignature());
        else
            System.out.println("Global advice   [Serializable]: " + thisJoinPointStaticPart.getSignature());
        return proceed(arg);
    }

    List<Serializable> around(List<Serializable> list) : listArgument(list) {
        System.out.println("Specific advice [List]:         " + thisJoinPointStaticPart.getSignature());
        return proceed(list);
    }

    Serializable around(Serializable serializable) : serializableArgument(serializable) {
        System.out.println("Specific advice [Serializable]: " + thisJoinPointStaticPart.getSignature());
        return proceed(serializable);
    }
}
Global advice   [Serializable]: Serializable de.scrum_master.aspectj.sample.TestApp.save(Serializable)
Specific advice [Serializable]: Serializable de.scrum_master.aspectj.sample.TestApp.save(Serializable)
Global advice   [List]:         List de.scrum_master.aspectj.sample.TestApp.save(List)
Specific advice [List]:         List de.scrum_master.aspectj.sample.TestApp.save(List)
 类似资料:
  • 我有一个采访问题-C#,是否可以在一个类中实现,从接口继承有两个具有相同名称和相同签名的方法?

  • 问题内容: 我正在尝试使用RSA 7.5和Websphere 7服务器开发IBM JAX_WS Web服务。因为我是一个初学者,所以我遵循Java类优先方法,即首先创建Java类,然后生成WSDL文件。 当我尝试创建wsdl文件时,出现异常: java.security.PrivilegedActionException:com.sun.xml.internal.bind.v2.runtime.I

  • 问题内容: 我正在用C#编写.NET Framework 3.5。 我正在尝试将某些Json解析为JObject。 Json如下: 当我尝试将此Json解析为JObject时,JObject仅了解LargeBox。SmallBox和MedBox的信息丢失。显然,这是因为它将“ TBox”解释为一个属性,并且该属性已被覆盖。 我从Delphi编码的服务中收到此Json。我正在尝试为该服务创建C#代理

  • 我有一个场景,其中一个url“serachUser”可能带有两个不同的值(请求参数)userId或UserName。 为此我创造了两种方法 但我得到模糊映射发现异常。Spring能处理这种情况吗?

  • 我们可以创建相同的GET URI但使用不同的查询参数吗? 例如,我有两个REST GET URI: 现在REST服务没有将两个GET方法识别为单独的,并且只将其视为声明为第一个的1 GET方法。 为什么会这样 如果您能引用任何资源,我们将不胜感激。

  • 我有两个类,它们具有相同的类名并使用相同的包名。但是,这两个类文件位于不同的目录中。这两个类之间的另一个不同之处是,每个类中都有其他类中没有的方法。本质上,我想将这些方法拆分为两个使用相同名称但不同文件夹的单独文件。 理论上,我认为这是可能的,因为Java编译器在构建输出时确实维护了目录结构。所以在运行时,如果在类中调用了一个方法,Java可能会在任何一个文件中找到该方法。 这可能吗?我使用的是I