在我的 Spring Boot 应用程序中,我针对一个使用“执行”成功工作的接口(interface)使用了切入点。我尝试将其转换为“内部”作为教程后的练习,但它不起作用,我不明白为什么。
这是服务接口(interface):
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”的切入点应该与 com.test.services 包中的任何方法匹配,但事实并非如此。我错过了什么吗?
最佳答案
可能是实现 MyService
的类定义在 com.test.services
以外的包中,比如
- 类似
com.test.services.impl
的子包或 - 完全不同的包,例如
com.test.app
.
如上所述Language semantics - Pointcuts在 AspectJ 文档中,
- 一些切入点类型,例如
execution()
或call()
(Spring AOP 中不可用)处理运行时结构(匹配签名), - 而其他人则喜欢
within()
或withincode()
处理词法结构(定义匹配代码的地方)。参见例如section "Program text-based pointcuts" .
如果我们有一个类 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..*+)
,但是您使用哪一个实际上取决于您的用例,并且在许多情况下太宽泛也不好。
关于java - 为什么我的 Spring AOP 在切入点内不起作用,但执行却起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68654715/