Skip to content

面试速答(先看这里)

**一句话结论:**首先,Spring的AOP其实是通过动态代理实现的,所以,想要让AOP生效,前提必须是动态代理生效,并且可以调用到代理对象的方法。

60秒标准回答:

首先,Spring的AOP其实是通过动态代理实现的,所以,想要让AOP生效,前提必须是动态代理生效,并且可以调用到代理对象的方法

什么情况下会不走代理对象的调用呢?

首先就是类内部的调用,比如一些私有方法调用,内部类调用,以及同一个类中方法的自调用等。如

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**首先就是类内部的调用,比如一些私有方法调用,内部类调用,以及同一个类中方法的自调用等。
  • **要点2:**以上,都是因为在对象内部直接调用其他方法,就会用原始对象直接调用了,不会调用到代理对象,所以代理会失效。
  • **要点3:**类似的还有一种情况,虽然不是对象的自调用,但是他也是因为没有调用到代理对象,那就是调用static方法,因为这类方法是属于这个类的,并不是对象的,所以无法被AOP。
  • **要点4:**还有一种方法,也无法被代理,那就是final方法,由于AOP是通过创建代理对象来实现的,而无法对final方法进行子类化和覆盖,所以无法拦截这些方法。
  • **要点5:**所以,那么总结一下就是以下几种情况,会导致代理失效,AOP不起作用:

**记忆锚点:**AOP → final → Spring → 什么情况下会不走代理 → 内部直接调用其他方法 → 其实是通过动态代理

追问准备:

  • 围绕「AOP」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「final」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「Spring」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

📄 ✅介绍一下Spring的AOP

打开文档:✅介绍一下Spring的AOP

首先,Spring的AOP其实是通过动态代理实现的,所以,想要让AOP生效,前提必须是动态代理生效,并且可以调用到代理对象的方法。

什么情况下会不走代理对象的调用呢?

首先就是类内部的调用,比如一些私有方法调用,内部类调用,以及同一个类中方法的自调用等。如:

java
//1
public class MyService {
    public void doSomething() {
        doInternal(); // 自调用方法
    }

    public void doInternal() {
        System.out.println("Doing internal work...");
    }
}

//2
public class MyService {
    public void doSomething() {
        doInternal(); // 自调用私有方法
    }

    private void doInternal() {
        System.out.println("Doing internal work...");
    }
}

//3
public class OuterClass {
    private class InnerClass {
        public void doSomething() {
            System.out.println("Doing something in inner class...");
        }
    }

    public void invokeInnerClassMethod() {
        InnerClass innerClass = new InnerClass();
        innerClass.doSomething(); // 调用内部类方法
    }
}

以上,都是因为在对象内部直接调用其他方法,就会用原始对象直接调用了,不会调用到代理对象,所以代理会失效。

类似的还有一种情况,虽然不是对象的自调用,但是他也是因为没有调用到代理对象,那就是调用static方法,因为这类方法是属于这个类的,并不是对象的,所以无法被AOP。

java
public class MyService {
    public static void doSomething() {
        // static 方法
    }
}

还有一种方法,也无法被代理,那就是final方法,由于AOP是通过创建代理对象来实现的,而无法对final方法进行子类化和覆盖,所以无法拦截这些方法。

java
public class MyService {
    public final void doSomethingFinal() {
        System.out.println("Doing something final...");
    }
}

所以,那么总结一下就是以下几种情况,会导致代理失效,AOP不起作用:

1、私有方法调用

2、静态方法调用

3、final方法调用

4、类内部自调用

5、内部类方法调用