十一出行去哪里?六个国内小众旅游地推荐,人少景美享受慢时光! 2025-06-16 12:30:37
陈炟谕·残酷的政治斗争 2025-06-01 13:23:21
黑屏:录制视频后,播放时画面是黑的。 2025-06-16 04:42:28
世预赛-中国男篮大胜中国台北队41分 周琦砍两双 2025-06-05 08:30:44
《怪物猎人世界》骨锤龙在哪?骨锤龙弱点解析 2025-06-12 03:16:04
非正常偶像漫画下拉式 2025-06-09 00:24:07
自制弹簧 2025-05-24 06:06:16
昆山论坛 2025-05-08 14:04:35
2026世界杯世亚预分组抽签今天下午4点举行,国足落位第二档 2025-06-06 22:00:44
《天堂2》 10级~20级快速升级攻略 有效的升级技巧和方法 ——天堂2 2025-06-15 03:46:46

面试专题:Spring核心容器IOC的理解、原理与实现

前言本文主要讲解Spring核心容器之一IOC(Inversion of Control,控制反转)。IOC是一种设计模式,它是依赖注入(Dependency Injection,DI)的一种实现方式。在Spring框架中,IOC是一种用于实现依赖注入的技术,它可以帮助开发人员更好地管理和组织代码,提高代码的可重用性和可维护性。IOC也是在面试中经常问到的一个点,本文就来讲一下对IOC理解、原理与实现。

IOC理解IOC就是控制反转:

原来的对象是由使用者来进行控制,有了spring之后,可以把整个对象交给spring容器来进行管理。 在需要的地方进行依赖注入就行,使用注解@Autowired,populateBean完成属性值的注入。

spring IOC容器:是使用map的结构来存储,在spring中一般存在三级缓存,singletonObjects存放完整的bean对象,整个bean的生命周期,从创建、使用、销毁的过程全部都是由容器来管理。

使用IOC的好处:降低代码耦合度。

传统模式,使用new对象的方式,但是这样不可以实现多态,比如 比如我创建一个person对象,里面有一个eat(Apple apple)方法,那么调用这个eat方法的类,需要传入苹果(Apple)对象,之后我的这个方法改成吃梨子了,这个方法又改成eat(Pear pear)了,调用eat方法的类,又需要把之前的苹果改成梨子,扩展性差。

于是出现了面向接口编程,我在eat方法里面传入水果(Fruit)接口,之后苹果,梨只需要实现接口即可,调用eat方法的类,想吃梨子就传入梨子,想吃苹果传入苹果即可。

面向接口编程,也是有缺点的,面向接口时,在调用处会有接口和实现类的耦合,比如一个接口Person多个实现类(Student,Teacher),那就要Person s = new Student();Person s = newTeacher(),所以就用Spring IOC容器来管理。使用IOC,解决了接口和实现类的耦合,调用方统一面向接口,然后使用是通过依赖注入指明调用那个实现类,这样实现类使用Service定义bean的名称,跟接口就解耦了,调用直接用两种方式指定:

1.用Java的Resource直接指定

代码语言:java复制 @Resource(name = "SysCaptchaService2")

private SysCaptchaService sysCaptchaService2; 2.Autowired配合Qualifier指定

代码语言:java复制 @Autowired

@Qualifier("SysCaptchaService")

private SysCaptchaService sysCaptchaService;IOC底层原理IOC底层主要是使用xml解析+反射+工厂模式实现,通过源码分析总结如下:

首先容器的创建过程,用到工厂模式BeanFactor接口的实现类DefaultListableBeanFactory创建bean工厂,先bean工厂设置一些参数(比如前置处理BeanPostProcessor、Aware接口)

然后通过加载解析bean对象,xml配置或者注解@Autowired,也就是准备定义BeanDifinition对象,这里也是解析xml配置

接下来就是一些扩展点的处理,也是BeanFactoryPostProcessor的处理包括展占位符处理PlaceholderConfigurerSupport(BeanFactoryPostProcessor子类),处理${password}等。

再通过反射(xml配置获取到全类名,得到Class对象,调用newInstance就可创建对象),BeanDifinition对象实例化成具体的bean对象,也就是先实例化,然后在初始化bean对象,填充属性,调用aware子类的方法,调用BeanPostProcessor前置处理,调用init-method,调用BeanPostProcessor后置处理。

初始化完成就,开始获取完整bean对象,getBean(),使用完成就如果要销毁就调用destroyMethod。

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!