IOC(控制反转)
IoC
(Inversion of Control
,控制倒转)。所谓IoC
,对于spring
框架来说,就是由spring
来负责控制对象的生命周期和对象间的关系。
在没有IOC时,我们通过new
等关键字等方式,自己实例化对象。而使用IOC只需要通过IOC容器去获取对象,所有的类的创建、销毁都由spring
来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring
。
IOC容器
Spring
中提供了两种IoC
容器:
BeanFactory
ApplicationContext
两个容器间的关系如下图:
ApplicationContext
是BeanFactory
的子类,所以,ApplicationContext
可以看做更强大的BeanFactory
。
无论使用哪个容器,我们都需要通过某种方法告诉容器关于对象依赖的信息,Spring提供以下几种配置对象依赖信息的方式:
- 通过注解来配置类和类的依赖关系
- 通过XML来配置类和类的依赖关系
- 通过编写代码来配置类和类的依赖关系
Spring IOC的过程
Spring
的IoC
容器在实现控制反转和依赖注入的过程中,可以划分为两个阶段:
- 容器启动阶段
Bean
实例化阶段
在上述两个阶段,Spring
提供了一种叫做BeanFactoryPostProcessor
的容器扩展机制。该机制允许我们在容器实例化相应对象之前,对注册到容器的BeanDefinition
所保存的信息做相应的修改,比如我们可以修改其中bean
定义的某些属性,为bean
定义增加其他信息等。
容器扩展机制具体参考:细说Spring——IoC详解(深入IoC实现)
容器启动阶段
(1)加载配置文件信息
容器创造对象的第一步,就是加载配置文件信息,我们已经知道我们主要通过xml
文件和注解的方式来告诉容器对象间的依赖信息。
(2)解析配置生成BeanDefinition
在BeanFactory
容器中,每一个注入对象都对应一个BeanDefinition
实例对象,该实例对象负责保存注入对象的所有必要信息,包括其对应的对象的class类型、是否是抽象类、构造方法参数以及其他属性等。当客户端向BeanFactory
请求相应对象的时候,BeanFactory
会通过这些信息为客户端返回一个完备可用的对象实例。
Spring通过使用加载解析配置文件的类BeanDefinitionReader
,读取配置文件并解析,之后将解析后的文件内容映射到相应的BeanDefinition
。
Bean实例化阶段
实例化流程图:
AOP(面向切面编程)
AOP(Aspect Oriented Programming,面向切面编程)是一种编程范式,提供从另一个角度来考虑程序结构以完善面向对象编程(OOP)
AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理、日志管理、权限控制等,封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
AOP相关概可以参考:细说Spring——AOP详解(AOP概览)
Spring默认采取的动态代理机制实现AOP,当动态代理不可用时(代理类无接口)会使用CGlib机制。
但Spring的AOP有一定的缺点:
- 只能对方法进行切入,不能对接口,字段,静态代码块进行切入(切入接口的某个方法,则该实现该接口的所有方法都会被切入)。
- 同一个类中的方法互相调用将不会使用代理类,即同一个类的方法相互调用不能触发AOP。
AOP的详细实现机制:AOP的实现机制
参考
- 重点好文:细说Spring
- 面试问烂的 Spring AOP 原理、SpringMVC 过程
- 理解Spring的AOP和IOC实现原理
- 我对AOP的理解