为什么我的SpringAOP在切入点内不工作,而执行却工作?

zrfyljdw  于 2023-03-16  发布在  Spring
关注(0)|答案(1)|浏览(123)

在我的Sping Boot 应用程序中,我在一个使用“执行”成功工作的接口上工作了一个切入点。我尝试将它转换为“内部”作为教程后的练习,但它不工作,我不知道为什么。
服务界面如下:

package com.test.services;

import com.test.model.MyObject;

public interface MyService {
    MyObject get(Long id);
}

以下是行之有效的方面:

package com.test.aop;

import org.aspectJ.lang.annoation.Aspect;
import org.aspectJ.lang.annoation.Before;
import org.aspectJ.lang.annoation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MyAspect {
    @Pointcut("execution(* com.test.services.MyService.*(..))")
    public void anyMyServiceMethod() {}

    @Before("anyMyServiceMethod()")
    public void beforeAnyServiceMethod() {
        System.out.println("HERE!");
    }
}

我把它改成了这个,它不工作了:

package com.test.aop;

import org.aspectJ.lang.annoation.Aspect;
import org.aspectJ.lang.annoation.Before;
import org.aspectJ.lang.annoation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MyAspect {
    @Pointcut("within(com.test.services.*)")
    public void anyMyServiceMethod() {}

    @Before("anyMyServiceMethod()")
    public void beforeAnyServiceMethod() {
        System.out.println("HERE!");
    }
}

从我所读到的内容来看,我认为上面使用“within”的切入点应该与包www.example.com中的任何方法匹配com.test.services,但事实并非如此。

htrmnn0y

htrmnn0y1#

实现MyService的类可能是在com.test.services以外的包中定义的,例如

  • com.test.services.impl之类的子包或
  • 一个完全不同的封装,比如com.test.app

正如AspectJ文档中所描述的Language semantics - Pointcuts

  • 一些切入点类型如execution()call()(在SpringAOP中不可用)处理运行时结构(匹配签名),
  • 而其他的如within()withincode()处理词法结构(其中定义了匹配的代码)。

因此,如果我们有一个类com.test.app.MyServiceImpl,你可以将你的切入点固定为within(com.test.services.*+),以便也匹配com.test.services包中定义的类的子类型。在execution()中,子类型的+是不必要的,因为MyServiceImpl也是一个MyService,即execution(* com.test.services.MyService.*(..))已经匹配。
另一方面,如果类名是com.test.services.impl.MyServiceImpl,那么切点within(com.test.services..*)(双点表示包含子包)也可以工作,但是它会再次排除其他包中的实现。最通用的一个是within(com.test.services..*+),但是使用哪一个实际上取决于您的用例,在许多情况下太宽泛也不好。

相关问题