【面试题】谈谈你对Spring的IOC和AOP的理解?

注意:文章若有错误的地方,欢迎评论区里面指正 🍭 

系列文章目录

参考文章:

  • https://pdai.tech/md/interview/x-interview-2.html#_10-1-spring

一.IOC(Inversion of Control)

1、IOC是什么?

Spring的IOC(Inverse of Control,控制反转)是Spring框架的一个核心概念,它是一种设计原则,用于实现软件组件之间的解耦。在传统的程序设计中,组件之间的依赖关系是由组件自身控制的,而在控制反转中,这种控制权被反转,由外部容器来管理。

2、IOC容器的作用

  • 管理依赖:IOC容器负责管理组件之间的依赖关系,组件不需要自己创建或查找它们的依赖项,而是由容器自动提供。

  • 创建对象:容器负责实例化、配置、组装应用程序中的所有对象。

  • 配置管理:Spring允许将配置元数据从代码中分离出来,通常使用XML或注解来配置,容器根据这些配置来创建和组装对象。

  • 生命周期管理:容器管理对象的生命周期,包括对象的创建、初始化、使用、销毁等。

  • 作用域管理:Spring支持不同的对象作用域,如单例(Singleton)、原型(Prototype)、会话(Session)、请求(Request)等。

3、IOC的实现原理

工厂模式 + 反射机制

示例:

public interface Fruit {
    void showType();
}


public class Apple implements Fruit{
    @Override
    public void showType() {
        System.out.println("我是一个苹果");
    }
}

public class Orange implements Fruit{
    @Override
    public void showType() {
        System.out.println("我是一个橘子");
    }
}

public class FruitFactory {
    /**
    * 说明: 工厂+反射
        * @param: className
        * @return: com.LYJ.study.Spring.IOC.Fruit
        * @author LYJ
    */
    public static Fruit getInstance(String className){
        Fruit fruit = null;
        try {
            fruit = (Fruit) Class.forName(className).getDeclaredConstructor().newInstance();
        }catch (Exception e){
            e.printStackTrace();
        }
        return fruit;
    }
}

//传统方式获取对象
public class Traditional {
    public static void main(String[] args) {
        Fruit apple = new Apple();
        Fruit orange = new Orange();
        apple.showType();
        orange.showType();
    }
}

//工厂+反射获取对象
public class Client {
    public static void main(String[] args) {
        Fruit apple = FruitFactory.getInstance("com.LYJ.study.Spring.IOC.Apple");
        apple.showType();

        Fruit orange = FruitFactory.getInstance("com.LYJ.study.Spring.IOC.Orange");
        orange.showType();

    }
}

二.AOP(Aspect Oriented Programming)

1、什么是AOP? 

AOP(Aspect-Oriented Programming,面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可扩展性和可维护性。

2、AOP实现原理?

Spring AOP是基于动态代理的,如果要代理的对象实现了某个接口,那么Spring AOP就会使用JDK动态代理去创建代理对象;而对于没有实现接口的对象,就无法使用JDK动态代理,转而使用CGlib动态代理生成一个被代理对象的子类来作为代理。

当然也可以使用AspectJ,Spring AOP中已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。使用AOP之后我们可以把一些通用功能抽象出来,在需要用到的地方直接使用即可,这样可以大大简化代码量。我们需要增加新功能也方便,提高了系统的扩展性。日志功能、事务管理和权限管理等场景都用到了AOP。

3、AOP有哪些概念?

  1. Jointpoint(连接点):具体的切面点点抽象概念,可以是在字段、方法上,Spring中具体表现形式是PointCut(切入点),仅作用在方法上。
  2. Advice(通知): 在连接点进行的具体操作,如何进行增强处理的,分为前置、后置、异常、最终、环绕五种情况。
  3. 目标对象:被AOP框架进行增强处理的对象,也被称为被增强的对象。
  4. AOP代理:AOP框架创建的对象,简单的说,代理就是对目标对象的加强。Spring中的AOP代理可以是JDK动态代理,也可以是CGLIB代理。
  5. Weaving(织入):将增强处理添加到目标对象中,创建一个被增强的对象的过程。

总结为一句话就是:在目标对象(target object)的某些方法(jointpoint)添加不同种类的操作(通知、增强操处理),最后通过某些方法(weaving、织入操作)实现一个新的代理目标对象。

4、AOP 有哪些应用场景? 

举几个例子:

  • 记录日志(调用方法后记录日志)
  • 监控性能(统计方法运行时间)
  • 权限控制(调用方法前校验是否有权限)
  • 事务管理(调用方法前开启事务,调用方法后提交关闭事务 )
  • 缓存优化(第一次调用查询数据库,将查询结果放入内存对象, 第二次调用,直接从内存对象返回,不需要查询数据库 )

5、有哪些AOP Advice通知的类型?

特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice。Spring AOP 使用一个 Advice 作为拦截器,在 JoinPoint “周围”维护一系列的拦截器。

  • 前置通知(Before advice) : 这些类型的 Advice 在 joinpoint 方法之前执行,并使用 @Before 注解标记进行配置。
  • 后置通知(After advice) :这些类型的 Advice 在连接点方法之后执行,无论方法退出是正常还是异常返回,并使用 @After 注解标记进行配置。
  • 返回后通知(After return advice) :这些类型的 Advice 在连接点方法正常执行后执行,并使用@AfterReturning 注解标记进行配置。
  • 环绕通知(Around advice) :这些类型的 Advice 在连接点之前和之后执行,并使用 @Around 注解标记进行配置。
  • 抛出异常后通知(After throwing advice) :仅在 joinpoint 方法通过抛出异常退出并使用 @AfterThrowing 注解标记配置时执行。

6、AOP实现的方式有哪些?

实现 AOP 的技术,主要分为两大类:

  • 静态代理 - 指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;
    • 编译时编织(特殊编译器实现)
    • 类加载时编织(特殊的类加载器实现)。
  • 动态代理 - 在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。
    • JDK 动态代理
      • JDK Proxy 是 Java 语言自带的功能,无需通过加载第三方类实现;
      • Java 对 JDK Proxy 提供了稳定的支持,并且会持续的升级和更新,Java 8 版本中的 JDK Proxy 性能相比于之前版本提升了很多;
      • JDK Proxy 是通过拦截器加反射的方式实现的;
      • JDK Proxy 只能代理实现接口的类;
      • JDK Proxy 实现和调用起来比较简单;
    • CGLIB
      • CGLib 是第三方提供的工具,基于 ASM 实现的,性能比较高;
      • CGLib 无需通过接口来实现,它是针对类实现代理,主要是对指定的类生成一个子类,它是通过实现子类的方式来完成调用的。

7、Spring AOP和AspectJ AOP有什么区别?

Spring AOP是属于运行时增强,而AspectJ是编译时增强。Spring AOP基于代理(Proxying),而AspectJ基于字节码操作(Bytecode Manipulation)。

Spring AOP已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。AspectJ相比于Spring AOP功能更加强大,但是Spring AOP相对来说更简单。

如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择AspectJ,它比SpringAOP快很多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小杰不秃头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值