控制反转——IoC
- 提出IoC的目的
为了解决对象之间的耦合度过高的问题,提出了IoC理论,用来实现对象之间的解耦。
- 什么是IoC
IoC是Inversion of Control的缩写,译为控制反转,不是什么技术,而是一种设计思想。IoC理论的观点主要是:借助于“第三方”实现具有依赖关系的对象之间的解耦。
传统程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象。而IoC是有专门一个容器来创建这些对象,即由IoC容器来控制对象的创建。
为什么称为反转? 因为容器帮我们查找及注入依赖对象,对象只是被动的接收依赖对象,所以称为反转。
什么反转了呢? 获取对象的过程反转了!!!
通俗的讲,IoC就是一个对象制造工厂,你需要什么,他就会给你送过去,你直接使用就可以啦。
- 依赖注入DI
控制被反转之后,获得依赖对象的过程由自身管理变为由IoC容器主动注入。于是给“控制反转”取了一个更合适的名字“依赖注入”。实际上给出了实现IoC的方法:注入!
依赖注入和控制反转是从不同的角度描述同一件事情,就是指通过引入IoC容器,利用依赖关系注入的方式,实现了对象之间的解耦。
- IoC的实现原理
1. 通过反射创建实例
2. 获取需要注入的接口实现类,并将其赋值給该接口
- IoC的好处
我们以USB作为例子:
- USB设备作为电脑主机的外部设备,在插入主机之前,与电脑主机没有任何的关系,只有被我们连接在一起之后,两者才发生联系,具有相关性。所以,无论两者中的任何一方出现什么的问题,都不会影响另一方的运行。这种特性体现在软件工程中,就是可维护性比较好,非常便于进行单元测试,便于调试程序和诊断故障。代码中的每一个Class都可以单独测试,彼此之间互不影响,只要保证自身的功能无误即可,这就是组件之间低耦合或者无耦合带来的好处。
- USB设备和电脑主机的之间无关性,还带来了另外一个好处,生产USB设备的厂商和生产电脑主机的厂商完全可以是互不相干的人,各干各事,他们之间唯一需要遵守的就是USB接口标准。这种特性体现在软件开发过程中,好处可是太大了。每个开发团队的成员都只需要关心实现自身的业务逻辑,完全不用去关心其它的人工作进展,因为你的任务跟别人没有任何关系,你的任务可以单独测试,你的任务也不用依赖于别人的组件,再也不用扯不清责任了。所以,在一个大中型项目中,团队成员分工明确、责任明晰,很容易将一个大的任务划分为细小的任务,开发效率和产品质量必将得到大幅度的提高。、
- 同一个USB外部设备可以插接到任何支持USB的设备,可以插接到电脑主机,也可以插接到DV机,USB外部设备可以被反复利用。在软件工程中,这种特性就是可复用性好,我们可以把具有普遍性的常用组件独立出来,反复利用到项目中的其它部分,或者是其它项目,当然这也是面向对象的基本特征。显然,IOC不仅更好地贯彻了这个原则,提高了模块的可复用性。符合接口标准的实现,都可以插接到支持此标准的模块中。
- 同USB外部设备一样,模块具有热插拔特性。IOC生成对象的方式转为外置方式,也就是把对象生成放在配置文件里进行定义,这样,当我们更换一个实现子类将会变得很简单,只要修改配置文件就可以了,完全具有热插拨的特性
- IoC框架的缺点
- 由于引入了第三方IoC容器,生成对象的步骤变得复杂,所以就会增加团队成员学习和认识的培训成本,并且在以后的运行维护中,还得让新加入者具备同样的只知识体系。
- 由于IoC容器生成对象是通过反射方式,在运行效率上有一定的损耗。
- 需要进行大量的配置工作,比较繁琐,对于一些小的项目而言,客观上可能加大了工作成本。
- 如果引入一个不成熟的框架产品,会影响到整个项目。
面向切面编程——AOP
面向切面编程(AOP),可以说是面向对象编程(OOP)的补充和完善。OOP引入继承、封装、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,如日志功能。日志代码往往横向散布在所有对象层次中,而与它对应的对象的核心功能毫无关系,如安全性、异常处理等。这种散布在各处的无关代码被称为横切。在OOP设计中,它导致了大量重复代码,从而不利于各个模块的重用。
AOP利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为“切面”。所谓“切面”,就是那些与业务无关,却为业务模块所共同调用的责任或逻辑封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
利用“横切”技术,AOP把软件系统分为两个部分:横切关注点和核心关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,它们经常发生在核心关注点,而且各处基本相似,如权限认证、日志等。AOP的作用就是,将核心关注点和横切关注点分离开来。
- 在哪里用到AOP
事务、日志、安全性等地方需要用到AOP
- Spring对AOP的支持
Spring中AOP代理由Spring的IoC容器负责生成、管理,其依赖关系也有IoC容器负责管理。因此AOP代理可以直接使用容器中其它bean实例作为目标,这种关系可由IoC容器的依赖注入提供。
- AOP的实现方式(Spring创建代理的方式):
1. 使用Java动态代理来创建AOP,默认方式
2. 使用Cglib动态代理。
二者的区别:需要代理的是接口时,使用Java动态代理;而需要代理的是类,使用Cglib代理。