spring面试题之AOP

面试的时候关于spirng的知识点中,AOP绝对是一大热点,那么该怎么回答关于AOP的面试问题呢,接下来,将我自己总结的关于AOP的面试问题分享给各位。

(1).Spring AOP用的是哪种设计模式?

代理模式。

通过代理,可以详细控制访问某个或者某类对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。

(2).谈谈你对代理模式的理解?

通过代理,控制对对象的访问,它的设计思路是:定义一个抽象角色,让代理角色和真实角色分别去实现它

真实角色就是实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用,它只关注真正的业务逻辑。

代理角色就是实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并在前后可以附加自己的操作。

(3).静态代理和动态代理有什么区别?

代理模式分为静态代理和动态代理,静态代理是我们自己创建一个代理类,而动态代理是程序自动帮我们生成一个代理。

  • 静态代理:

        静态代理需要创建真实角色和代理角色,分别实现抽象角色,真实角色可以直接实现,代理类需要将真是的对象传进来。

            (1).接受真实对象

            (2).通过构造方法传进来真实的对象

    

  •  动态代理:

        动态代理比静态代理使用的更广泛,在本质上,动态代理的代理类不用我们来管,交给工具去生成代理类即可。

  1.  JDK 动态代理:

            我们不需要去创建代理类,那我们只需要编写一个动态处理器就可以了,真正的代理对象由JDK在运行时为我们动态的创建。

            动态代理处理类:

                (1).接收真实对象

                (2).通过构造方法传进来真实的对象

                (3).给真实对象生成一个代理对象实例

        相对于静态代理,JDK 动态代理大大减少了我们的开发任务,同时减少了对业务接口的依赖,降低了耦合度。JDK 动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前第啊用InvokeHandler来处理。

        JDK 动态代理的特点:JDK 实现动态代理需要实现类通过接口定义业务方法。

  2. CGLIB 动态代理:

            对于没有接口的类,就需要CGLIB。

            原理:通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。采用继承,不能对final修饰的类进行代理

            使用CGLIB需要实现MethodInterceptor接口,并重写intercept方法,在该方法中对原始要执行的方法前后做增强处理。该类的代理对象可以使用代码中的字节码增强器来获取。 

        CGLIB创建的动态代理对象比JDK创建的动态代理对象的性能更高,但是CGLIB创建代理对象时所花费的时间却比JDK多得多。所以对于单例对象,因为无需频繁创建对象,用CGLIB合适,反之使用JDK要合适一些。

            CGLIB采用动态创建子类的方法,对于final修饰的方法无法进行代理。

    要代理的类中可能不止一种方法,有时候需要对特定的方法进行增强处理,可以对传入的method参数进行方法名的判断,再做相应的处理。

(4).Spring AOP采用哪种代理?

JDK 动态代理和CGLIB 动态代理均是实现Spring AOP的基础。 

    在Spring 5源码中:

        (1).判断是否是最优化的,判断是否是代理类,判断代理的对象是否又实现接口。前两个判断默认返回false

        (2).判断目标类是否为null,若为null,则抛出异常 (AopConfigException) 

        (3).判断目标类是否是接口或者目标类是否是Proxy类型,若是则使用JDK动态代理

        (4).若配置使用CGLIB进行动态代理或者目标类没有接口,那么使用CGLIB的方式创建代理对象

        (5).若(2)、(3)、(4)方法中没有一个为true,那使用JDK的提供的代理方式生成代理对象。

    如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP;如果目标对象没有实现接口,则采用CGLIB库,Spring会自动在JDK动态代理和CGLIB动态代理之间转换。

你可能感兴趣的:(Java)