You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

是否可以通过Spring AOP切入抽象类中的protected方法?

问题核心原因及修正方案

1. 切点表达式配置错误

你当前的切点直接写@annotation(EntityCreated)没有指定注解的全限定类名,Spring AOP无法定位到你自定义的注解,必须写注解的完整包路径。

2. 切面类位置配置错误

你将EntityAspect定义为EntityCreated注解的内部类,Spring组件扫描默认不会识别内部类的@Component注解,需要将切面类单独抽为顶层类,放在组件扫描可覆盖的包路径下。

3. AOP代理机制限制

Spring默认的JDK动态代理仅支持拦截接口的public方法,要拦截protected方法必须开启CGLIB代理:

  • Spring Boot项目在application.properties添加配置:
spring.aop.proxy-target-class=true
spring.aop.auto=true
  • 传统Spring XML配置添加:
<aop:aspectj-autoproxy proxy-target-class="true"/>

4. 方法内部调用拦截失效

如果是子类内部通过this调用doSomething方法,不会走代理对象,切面自然无法触发,需要通过代理对象调用:

// 子类调用示例
(AopContext.currentProxy() as 你的子类类型).doSomething(p1, p2)

5. 注解不继承问题

如果子类重写了doSomething方法,父类方法上的@EntityCreated默认不会被子类继承,需要给注解添加@Inherited元注解,或者子类重写的方法也手动添加@EntityCreated。

修正后的完整代码示例

注解定义

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@Inherited // 可选,需要子类继承注解时添加
annotation class EntityCreated

切面类

@Aspect
@Component
class EntityAspect {
    // 替换com.yourpackage为你自己的注解所在包路径
    @AfterReturning(value = "@annotation(com.yourpackage.EntityCreated)", returning = "entity")
    fun afterEntityCreated(joinPoint: JoinPoint, entity: SomeEntity) {
        // 这里执行你的自定义逻辑,entity就是方法返回的实例
    }
}

抽象类加注解

abstract class SomeAbstractClass : ServiceOne, ServiceTwo {
  @EntityCreated
  protected fun doSomething(p1: String, p2: Int): SomeEntity {
    // 原有业务逻辑
    return SomeEntity()
  }
}

如果上述方案还是无法满足需求,可以改用AspectJ静态织入,完全绕过Spring代理的限制,支持所有方法修饰符和内部调用场景,只需要额外配置AspectJ编译插件即可。

内容的提问来源于stack exchange,提问作者hrabrica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 05:06:04