前言
本文主要讲解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腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!