AspectJ技术咨询:能否重写父类方法并通过super调用父类原方法?
当然可以!用AspectJ实现类似“重写父类方法+调用super原方法”的效果
完全没问题,AspectJ的Around通知正好能满足你的需求——它允许你拦截目标方法的执行,插入自定义逻辑,并且可以选择是否调用原方法(这就对应你说的super调用父类原方法的场景)。
先把你没写完的子类代码补全,方便演示:
package test; public class Child extends Parent { // 假设子类原本没有重写doSomething方法 }
接下来直接上切面实现代码,一看就懂:
package test; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @Aspect public class ParentMethodInterceptor { // 切点定位到Parent类的doSomething方法,包括所有子类调用该方法的场景 @Around("execution(void test.Parent.doSomething())") public void interceptAndOverride(ProceedingJoinPoint joinPoint) throws Throwable { // 这里是你自定义的"重写"逻辑,相当于子类重写方法里的自定义代码 System.out.println("Aspect: 我是新增的前置逻辑,替代/补充父类方法"); // 调用原方法——这一步就等价于在子类重写方法里调用super.doSomething() joinPoint.proceed(); // 还可以添加后置逻辑,按需选择 System.out.println("Aspect: 父类原方法执行完了,我来收尾"); } }
运行效果
当你执行Parent类的main方法时,输出会变成:
Aspect: 我是新增的前置逻辑,替代/补充父类方法 Parent is doing something Aspect: 父类原方法执行完了,我来收尾
关键细节说明
- 切点表达式精准度:如果只想拦截子类调用父类方法的场景,可以把切点改成
execution(void test.Child.doSomething());如果要匹配所有继承Parent的子类,用execution(void test.+.doSomething()) && target(test.Parent)更灵活。 - 原方法调用的控制:
joinPoint.proceed()必须显式调用,否则原父类方法不会执行(相当于完全替换原方法);如果需要传递参数给原方法,可以用proceed(Object[] args)。 - 织入方式:要确保AspectJ的织入生效,你可以选择编译时织入(CTW)(用AspectJ编译器ajc编译代码)或者加载时织入(LTW)(通过JVM参数配置织入代理)。
如果子类本身已经重写了doSomething,你想在切面里强制调用父类的原方法,这时候可以通过反射实现,但一般不推荐——AspectJ的设计初衷是通过切点拦截来实现横切逻辑,而非直接绕过子类重写。
内容的提问来源于stack exchange,提问作者vesuvius
相关产品推荐
相关产品推荐

