《Spring》IOC实现原理

1. 概述

IOC(Inversion of Control)控制反转,也称为DI(Dependency Injection)依赖注入。所谓IOC ,就是把原先代码里需要开发者实现的对象创建和关系依赖,反转交给SpringIOC容器管理对象的生命周期和对象之间的依赖关系。

Spring通过配置文件描述Bean及Bean之间的依赖关系(或者是注解@annotation),利用Java语言的反射功能实例化Bean并建立Bean之间的依赖关系。

Spring启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配Bean之间的依赖关系,最后将Bean保存到Spring容器中的Bean缓存池中,其中Bean缓存池是由ConcurrentHashMap实现

2. 依赖倒置

假设我们设计一辆汽车:先设计轮子,然后根据轮子大小设计底盘,接着根据底盘设计车身,最后根据车身设计好整个汽车。这里就出现了一个依赖关系:汽车依赖车身,车身依赖底盘,底盘依赖轮子

这样的设计看起来没问题,但是可维护性却很低。假设设计完工之后,上司却突然说根据市场需求的变动,要我们把车子的轮子设计都改大一码。这下我们就蛋疼了:因为我们是根据轮子的尺寸设计的底盘,轮子的尺寸一改,底盘的设计就得修改。

同样因为我们是根据底盘设计的车身,那么车身也得改,同理汽车设计也得改——整个设计几乎都得改!我们现在换一种思路。我们先设计汽车的大概样子,然后根据汽车的样子来设计车身,根据车身来设计底盘,最后根据底盘来设计轮子。这时候,依赖关系就倒置过来了:轮子依赖底盘, 底盘依赖车身, 车身依赖汽车

这时候,上司再说要改动轮子的设计,我们就只需要改动轮子的设计,而不需要动底盘,车身,汽车的设计了。这就是依赖倒置原则——把原本的上层依赖底层倒置过来,变成底层依赖上层。上层决定需要什么,底层就去实现这样的需求,而上层并不关注底层怎么实现的。这样就不会出现前面的牵一发而动全身的情况。

3. 控制反转

控制反转是依赖倒置原则的一种代码设计的思路,具体采用的方法是依赖注入(Dependency Injection)。所谓依赖注入,上层控制底层,底层类作为参数传入上层类

4. 常用容器

4.1 BeanFactory

BeanFactory是Spring框架的基础设施,是IOC容器的基础接口,所有的容器都是从它这里继承实现而来。BeanFactory作为SpringIOC容器,为了能够明确描述各个对象间的依赖关系,Spring提供了三种管理方式:

  1. 在XML中进行显式配置。
  2. 在Java中进行显式配置。
  3. 注解方式。

Spring提供了三种注入方式

  • 构造方法注入。
  • setter方法注入。
  • 注解方式注入。

4.2 ApplicationContext

ApplicationContext是Spring提供的一个高级的IOC容器,面向使用Spring框架的开发者,它除了能够提供IOC容器的基本功能外,还为用户提供了以下的附加服务:

  • BeanFactory:能够管理和装配Bean。
  • ResourcePatternResolver:能够加载资源文件。
  • MessageResource:能够实现国际化等功能。
  • ApplicationEventPublisher:能够注册监听器,实现监听机制。

Spring自带多种类型的应用上下文:

  1. AnnotatinonConfigApplicationContext:从一个或多个基于Java的配置类中加载Spring应用上下文。
ApplicationContext context = new AnnotatinonConfigApplicationContext(com.cmos.DemoConfig.class);
  1. AnnotationConfigWebApplicationContext:从一个或多个基于Java的配置类中加载SpringWeb应用上下文。
  2. ClassPathXmlApplicationContext:从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源。
ApplicationContext context = new ClassPathXmlApplicationContext("demo.xml");
  1. FileSystemXmlApplicationContext:从文件系统下的一个或多个XML配置文件中加载上下文定义。
ApplicationContext context = new FileSystemXmlApplicationContext("c:/demo.xml");
  1. XmlWebApplicationContext:从Web应用下的一个或多个XML配置文件中加载上下文定义。

5. Bean的作用域

  • singleton:这种Bean范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个Bean的实例,单例的模式由BeanFactory自身来维护。
  • prototype:原形范围与单例范围相反,为每一个Bean请求提供一个实例。
  • request:在请求Bean范围内会为每一个来自客户端的网络请求创建一个实例,在请求完成以后,Bean会失效并被垃圾回收器回收。
  • session:与请求范围类似,确保每个Session中有一个Bean的实例,在Session 过期后,Bean会随之失效。
  • global-session:global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多 portlet。如果你想要声明让所有的 portlet 共用全局的存储变量的话,那么这全局变量需要存储在global-session 中。全局作用域与Servlet中的Session 作用域效果相同。

6. Bean的生命周期

  1. Spring对Bean实例化;
  2. Spring将值和Bean的引用注入到Bean对应的属性中;
  3. 如果Bean实现了BeanNameAware接口,Spring将调用setBeanName()方法传递Bean的ID到BeanFactory中;
  4. 如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanFactroy()方法,将BeanFactory容器实例传入,便于Bean够获取配置他们的BeanFactory的引用
  5. 如果Bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将Bean所在应用上下文的引用传进来,便于bean获取它所在的Spring容器
  6. 如果Bean实现了BeanPostProcessor接口,Spring将调用postProcessBeforeInitialization()方法,该方法在Bean初始化之前调用。如果Bean在Spring配置文件中配置了init-method属性,该方法将会自动调用。
  7. 如果Bean实现了InitializingBean接口,Spring将调用它的afterPropertiesSet()方法,当Bean的所用属性被设置完成之后调用该方法;
  8. 如果Bean实现了BeanPostProcessor接口,Spring将调用它的postProcessAfterInitialization()方法,在Bean初始化完成之后调用;
  9. 此时Bean准备就绪;
  10. 如果Bean实现了DisposableBean接口,spring将调用它的destory()方法。如果Bean在Spring配置文件中配置了destory-method属性,该方法将会自动调用。

  • 9
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringIOC(Inverse of Control)实现原理是通过IOC容器来实现的。IOC容器负责实例化、定位、配置应用程序中的对象,并建立这些对象间的依赖关系,从而实现对象之间的松耦合。 在Spring中,通过配置文件或注解的方式告诉Spring哪些Bean需要进行管理,Spring会根据配置文件或注解来实例化这些Bean,并将它们放入IOC容器中。当我们需要使用这些Bean时,只需从IOC容器中获取即可,而不需要手动创建对象。这样就实现了将控制对象创建的过程反转给Spring容器来管理的效果。 SpringIOC容器充当了一个类似于餐馆的角色,我们只需要告诉Spring哪些Bean需要进行管理,然后通过指定的方式从IOC容器中获取相应的Bean。Spring提供了多种类型的IOC容器,例如基于XML配置的ApplicationContext,基于注解的AnnotationConfigApplicationContext等等。无论使用哪种类型的IOC容器,Spring都会负责创建和管理Bean的生命周期,并根据依赖关系进行自动注入。 总结来说,SpringIOC实现原理是通过IOC容器管理Bean的实例化、定位和配置,实现对象之间的解耦,并提供便利的方式来获取和使用这些Bean。通过IOC容器,我们可以更加灵活地组织和管理应用程序的对象。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [springIoc实现原理](https://download.csdn.net/download/zhangcongyi420/11131211)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [一文带你深入剖析Spring IOC 实现原理](https://blog.csdn.net/SQY0809/article/details/118678588)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值