在我的 Spring 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”的切入点应该匹配包 com.test.services 中的任何方法,但事实并非如此。我错过了什么吗?
很可能实现
MyService
的类是在com.test.services
以外的包中定义的,比如
com.test.services.impl
或com.test.app
.如 AspectJ 文档中所述语言语义 - 切入点,
execution()
或 call()
(在 Spring AOP 中不可用)处理运行时结构(匹配签名),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..*+)
,但是你用哪个真的取决于你的用例,太宽泛在很多情况下也不好。