Spring 面试

你对Spring的理解?

Spring是一个轻量级的容器框架,最主要的特点就是IOC和AOP。

  • IOC:指的是控制反转,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。我们将控制权交由Spring容器统一进行管理,从而实现松耦合。
  • AOP:是一个面向切面的编程,对代码某些类似的方面做一个切割,在不改变原有代码情况下进行一个增强功能的操作,一搬使用的就是用jdk或者cglib动态代理方式实现,通常用来做日志,权限控制,事务等,像事务这种的话,一般使用注解的方式,因为比较简单。

什么是IOC?Spring IOC怎么管理Bean之间的依赖关系,怎么避免循环依赖?

  • IOC(Inversion of Control,控制反转)是指将对象的创建和管理控制权从应用程序代码转移到容器中,由容器负责对象的创建、初始化和管理。在Spring中,IOC容器负责创建和管理Bean(应用程序中的对象)。
  • Spring IOC通过依赖注入(Dependency Injection,DI)来管理Bean之间的依赖关系,主要有以下几种方式:
    • 构造函数注入:通过Bean的构造函数注入依赖对象,在配置文件或使用注解时指定构造函数的参数。
    • Setter方法注入:通过Bean的Setter方法注入依赖对象,Spring容器在创建Bean后调用Setter方法设置依赖。
    • 接口注入:较少使用,Bean实现特定接口,接口中定义设置依赖对象的方法。
      避免循环依赖:
  • Spring通过三级缓存机制来解决大部分的循环依赖问题。在创建Bean时,先将Bean的早期引用(未完全初始化的Bean)放入一级缓存(singletonObjects)中,当需要依赖其他Bean时,从缓存中查找。如果在创建过程中发现循环依赖,对于单例Bean,Spring利用二级缓存(earlySingletonObjects)存储早期引用,通过三级缓存(singletonFactories)生成代理对象或提前暴露Bean的引用,来打破循环。
  • 对于基于构造函数的循环依赖,Spring无法自动解决,可通过使用@Lazy注解实现延迟加载,或者调整设计来避免。

讲讲静态代理模式的优点及其瓶颈?

  • 优点
    • 职责清晰:代理类和目标类的职责明确,代理类专注于增强功能(如权限校验、日志记录等),目标类专注于核心业务逻辑,使代码结构更清晰,便于维护。
    • 扩展性好:如果需要对目标类的功能进行增强,只需修改代理类,无需改动目标类,符合开闭原则。例如,为一个文件读取类添加日志记录功能,通过静态代理,在代理类中记录日志,不影响原文件读取类的代码。
    • 保护目标对象:代理类可以控制对目标类的访问,在某些情况下,防止外部直接访问目标类,起到一定的保护作用。
  • 瓶颈
    • 代理类过多:当有多个目标类需要代理时,需要编写大量的代理类,导致代码量增加,开发和维护成本上升。例如,项目中有10个不同的业务类都需要添加权限校验功能,就需要编写10个对应的代理类。
    • 缺乏灵活性:静态代理类在编译时就已经确定了代理的目标类,运行时不能动态改变。如果业务需求发生变化,需要代理其他目标类,就需要重新编写代理类。

对Java接口代理模式的实现原理的理解是什么?

  • 目标类和代理类实现同一个接口,这保证了代理类和目标类具有相同的行为定义。例如,定义一个UserService接口,包含loginregister等方法,目标类UserServiceImpl实现该接口完成具体业务逻辑,代理类UserServiceProxy也实现该接口。
  • 代理类持有目标类的引用,在代理类的方法中,先执行一些增强逻辑(如权限检查、日志记录等),然后通过目标类的引用调用目标类的方法来执行实际业务逻辑,最后还可以执行一些后续增强逻辑(如资源清理等)。例如,在UserServiceProxylogin方法中,先记录用户登录日志,然后调用UserServiceImpllogin方法进行登录验证,登录成功后记录登录结果日志。

如何使用Java反射实现动态代理?

Java反射实现动态代理主要通过java.lang.reflect.Proxy类和InvocationHandler接口。

谈谈对Cglib类增强动态代理的实现方式?

  • Cglib通过继承目标类来创建代理类,代理类是目标类的子类。
  • 利用字节码处理框架(如ASM),在运行时动态生成代理类的字节码。
  • 在代理类中,重写目标类的方法,在重写的方法中织入增强逻辑(如在方法调用前后添加日志记录、事务管理等代码),然后通过super关键字调用目标类的原方法,完成方法的执行。

什么是AOP?AOP的应用场景有哪些?

AOP(Aspect - Oriented Programming,面向切面编程)是一种编程范式,旨在将横切关注点(如日志记录、事务管理、权限控制、缓存管理等)从业务逻辑中分离出来,形成独立的切面(Aspect),然后在运行时将这些切面动态织入到目标对象的方法执行过程中。
应用场景:

  • 日志记录:在方法执行前后自动记录日志,便于系统调试和监控。
  • 事务管理:为业务方法自动添加事务控制,确保数据一致性和完整性。
  • 权限控制:在方法调用前检查用户权限,防止非法访问。
  • 性能监控:统计方法的执行时间,分析性能瓶颈。
  • 缓存管理:在方法调用前后检查缓存,减少数据库访问。

讲解OOP与AOP的简单对比?

  • 关注点不同:OOP(Object - Oriented Programming,面向对象编程)关注的是将业务逻辑封装成对象,通过对象之间的交互来完成业务功能,强调类、对象、继承、封装和多态等概念;AOP关注的是将横切关注点从业务逻辑中分离出来,以切面的形式对多个对象的共同行为进行统一管理。
  • 解决的问题不同:OOP主要解决业务逻辑的模块化和可维护性问题;AOP主要解决在OOP中横切关注点的代码重复和分散问题,例如多个业务类都需要日志记录、事务管理等功能,在OOP中会导致这些代码在多个类中重复出现,而AOP可以将这些功能集中在切面中实现。
  • 关系:AOP不是对OOP的替代,而是对OOP的补充和完善,两者结合可以更高效地构建复杂的软件系统。

讲解JDK动态代理和CGLIB代理原理以及区别?

  • JDK动态代理原理:JDK动态代理基于Java反射机制,要求目标对象必须实现至少一个接口。代理类实现与目标对象相同的接口,在运行时通过Proxy.newProxyInstance方法动态生成代理类实例。当调用代理对象的方法时,实际调用的是InvocationHandlerinvoke方法,在该方法中通过反射调用目标对象的实际方法,并可在前后添加增强逻辑。
  • CGLIB代理原理:CGLIB通过继承目标类来创建代理类,使用字节码处理框架(如ASM)在运行时动态生成代理类的字节码。代理类重写目标类的方法,在重写的方法中织入增强逻辑,然后通过super关键字调用目标类的原方法。
  • 区别
    • 代理对象的创建条件:JDK动态代理要求目标对象实现接口;CGLIB代理不需要目标对象实现接口,可以直接代理类。
    • 性能:在创建代理对象时,JDK动态代理基于反射,创建速度相对较慢;CGLIB基于字节码生成,创建速度相对较快。在代理对象的方法调用时,JDK动态代理的反射调用开销相对较大,CGLIB的方法调用通过直接调用子类方法,开销较小。不过随着JVM的优化,两者在实际应用中的性能差异并不明显。
    • 应用场景:如果目标对象实现了接口,优先使用JDK动态代理;如果目标对象没有实现接口,或者为了避免创建接口带来的额外复杂性,可使用CGLIB代理。

BeanFactory和FactoryBean有什么区别,BeanFactory和ApplicationContext又有什么不同?

  • BeanFactory和FactoryBean的区别
    • 概念不同BeanFactory是Spring容器的顶层接口,提供了基本的Bean管理和获取功能,是Spring IOC容器的基础;FactoryBean是一个接口,实现该接口的类用于创建其他Bean,是一个工厂Bean。
    • 作用不同BeanFactory用于管理和获取普通Bean实例;FactoryBean用于创建特定类型的Bean实例,通过FactoryBean创建的Bean不是FactoryBean本身,而是其getObject方法返回的对象。若要获取FactoryBean本身,需在Bean名称前加&符号。
  • BeanFactory和ApplicationContext的区别
    • 功能丰富度ApplicationContext继承自BeanFactory,除具备BeanFactory的基本功能外,还提供了更多功能,如国际化支持、事件发布机制、资源加载等。
    • 初始化方式BeanFactory采用延迟加载,只有在获取Bean时才创建和初始化Bean;ApplicationContext在启动时会预加载所有单例Bean,可在系统启动时发现配置错误。
    • 应用场景BeanFactory适用于资源有限、对性能要求较高且不需要太多扩展功能的场景;ApplicationContext适用于大多数企业级应用开发,提供更丰富的功能和便捷的开发体验。

谈谈Spring Bean创建过程中的设计模式?

  • 工厂模式:Spring IOC容器是一个大型工厂,负责创建和管理Bean。通过配置信息(如XML配置文件或注解),Spring容器根据不同的Bean定义创建相应的Bean实例,就像工厂按照不同的生产要求制造产品。
  • 单例模式:Spring容器默认创建的Bean是单例的,在整个应用中,一个Bean定义只会创建一个实例。Spring通过内部的单例注册表(如ConcurrentHashMap)来存储和管理单例Bean,确保在多线程环境下正确创建和获取单例Bean,避免重复创建,节省资源。
  • 策略模式:在Bean的创建过程中,针对不同类型的Bean(如普通Bean、FactoryBean等),采用不同的创建策略。普通Bean通过反射调用构造函数创建,FactoryBean通过调用其getObject方法创建,体现了策略模式中针对不同情况采用不同算法或策略的思想。
  • 观察者模式ApplicationContext中的事件发布机制运用了观察者模式。当Bean创建完成、销毁等事件发生时,ApplicationContext会发布相应事件,实现了ApplicationListener接口的监听器会收到通知并进行处理,实现了对象之间的解耦和事件驱动的编程模型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值