12

我想为带有特定注释的私有方法创建一个切入点。但是,当注释位于下面的私有方法上时,不会触发我的方面。

@Aspect
public class ServiceValidatorAspect {
    @Pointcut("within(@com.example.ValidatorMethod *)")
    public void methodsAnnotatedWithValidated() {
}

@AfterReturning(
            pointcut = "methodsAnnotatedWithValidated()",
            returning = "result")
    public void throwExceptionIfErrorExists(JoinPoint joinPoint, Object result) {
         ...
}

服务接口

public interface UserService {

    UserDto createUser(UserDto userDto);
}

服务实施

    public class UserServiceImpl implements UserService {

       public UserDto createUser(UserDto userDto) {

             validateUser(userDto);

             userDao.create(userDto);
       }

       @ValidatorMethod
       private validateUser(UserDto userDto) {

            // code here
       }

但是,如果我将注释移动到公共接口方法实现createUser,则会触发我的方面。我应该如何定义我的切入点或配置我的方面以使我的原始用例正常工作?

4

2 回答 2

30

8. Spring 面向切面编程

由于 Spring 的 AOP 框架基于代理的性质,根据定义,受保护的方法不会被拦截,对于 JDK 代理(这不适用)和 CGLIB 代理(这在技术上可行但不推荐用于 AOP 目的)都是如此。因此,任何给定的切入点都只会与公共方法匹配!

如果您的拦截需求包括受保护/私有方法甚至构造函数,请考虑使用 Spring 驱动的原生 AspectJ 编织而不是 Spring 的基于代理的 AOP 框架。这构成了具有不同特点的不同AOP使用模式,所以在做决定之前一定要先熟悉编织。

于 2013-02-26T16:24:56.860 回答
1

切换到 AspectJ 并使用特权方面。或者更改应用程序的设计以适应 Spring AOP 的限制。我的选择是功能更强大的 AspectJ。

于 2013-02-26T20:36:22.093 回答