本文根据极客学院的《Spring之IOC》视频课程编写。
Spring概况
Spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架,主要是为了解决企业应用开发的复杂性而诞生的。
- 功能:使用基本的JavaBean代替EJB
- 范围:适用于任何java应用
-
核心:IOC和AOP
分层、一站式、轻量级开源框架。
Spring之IOC
1. IOC开发模式和和传统开发模式之间的区别:
- IOC(控制反转),是spring的核心。对于spring框架来说,就是由spring来复杂控制对象的生命周期和对象间的关系。
- 举例说明:
传统开发模式:对象之间相互依赖。
在一个对象中,如果要使用另一个对象,就必须得到它,自己new一个,或者从JNDI中查询一个,使用完之后还必须将对象销毁。
IOC开发模式:IOC容器安排对象之间的依赖。
类似于通过婚介找对象
所有的类,都会在spring容器中,告诉spring对自己的描述,对需要对象的描述。spring会在程序运行过程适当的时候,将你需要的东西主动送给你,同时把你交给其他需要你的东西。所有类的创建销毁都由spring来控制。
控制对象生存周期的不再是引用他的对象,而是spring容器。对某个具体的对象而言,以前,是它控制其他对象,现在,是所有的对象都被spring控制。此谓控制反转。
2.IOC理论知识:
- 把复杂系统分解为相互合作的对象,这些对象类通过封装以后内部实现,对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活的被重用和扩展 。
- 简言之,借助于第三方来实现对具有依赖关系的对象之间的解耦。
IOC容器控制所有对象之间的关系,这使得IOC容器成为了整个系统的关键核心,起到类似粘合剂的作用,把系统中所有对象粘合在一起发挥作用 。
把中间的IOC容器拿掉,就是我们要实现整个系统所完成的全部内容。此时,ABCD四个对象之间没有了耦合关系毫无联系。 这样,当我们实现A的时候,无需考虑其他几个对象。所以开发者只要实现自己的类就可以了。
在未引入IOC容器时,对象之间相互依赖。当对象A需要初始化或者运行到某一点时,自己必须生动的创建对象B,或者使用已有的对象B,控制权在自己手上。
引入IOC容器后,对象A和对象B之间失去了直接的联系。当对象A运行到需要对象B的时候,IOC容器会主动将一个对象B注入到对象A需要对象B的地方。
整个过程,对象A对对象B的控制从主动变成了被动,控制权颠倒。
3. IOC之依赖注入DI
依赖注入- 控制反转:是指获得依赖对象的过程被反转。
- 控制反转之后,获得依赖对象的过程,由自身的管理,变成了由IOC容器主动的注入。所以,IOC的另一个名字就是依赖注入。其实这给出了实现IOC容器的方法,也即注入。
- 电脑主机与USB设备-一个常见的依赖注入的例子。
电脑主机通过USB接口读取USB设备的资源。当电脑需要读取一个资源时,我会主动将外部设备通过USB接口,接到主机中。电脑无需关心外部接的是U盘还是硬盘还是其他的。直接通过USB接口读取需要的资源。此过程中,我就扮演一个IOC容器的角色。所有对象的创建销毁都由我负责。每个对象本身都不用管。当电脑主机需要读取文件时,我就把它所需要的外部设备帮他挂接上。 - IOC容器就是一个对象制造工厂。需要什么,他就传送给你,你就直接使用什么就可以。不需要关心对象是怎么生成的,也不需要关心对象是怎么销毁的。IOC容器将实现组件间的关系从程序内部,提炼到了外部容器,也即由容器在程序运行期间,将组件间需要的某种依赖关系,动态的注入到组件当中。
4. IOC的好处
IOC在编程过程中不会对业务对象构成很强的侵入性。使用IOC之后,对象具有更好的可实行性,可重用性和可扩展性。
-
降低组件之间的耦合度
使用USB比使用内部硬盘有什么好处呢?
USB设备作为电脑主机的外部设备在插入主机之前,和主机之间没有任何关系,只有被我们插入到主机的USB接口后,两者才发生了联系,具有相关性。无论两者中任何一方出现问题,都不会影响另一方运行。这体现在软件工程中也就是可维护性。便于进行单元测试,便于调试程序和诊断故障,代码中的每一个class都可以单独测试,彼此之间互不影响,只要保证自身功能无误即可。这就是代码低耦合或无耦合带来的好处。 -
提高开发效率和产品质量
主机和USB设备的无关系的另一个好处就是,生产主机的厂商和生产USB设备的厂商完全可以是两个人。各干各事,唯一需要遵守的就是USB标准。在软件开发中,就体现在,开发团队的每个人都只需要关心实现自身的业务逻辑,不须关心其他人的工作进度,因为自身的任务和别人的毫无关系,可以单独测试,也不依赖于别人的任务。在大中型开发项目中,可以将一个大的任务划分为几个小的任务,分工明确,提高效率。 -
统一标准,提高模块的可复用性
例如USB设备可以迁移到电脑主机,迁移到DV机,可以迁移到任何支持USB的设备,可以被反复利用。在软件工程中,这就是可复用性。在开发过程中,把具有普遍性、常用的组件独立出来,反复利用到项目的其他部分或者其他项目,当然,这也是面向对象的特性。IOC提高了模块的可复用性,符合接口标准的实现,都可以迁移到支持此标准的模块当中。 -
模块具有热插拔特性
类似于USB的即插即用。IOC把对象生成放到了外置文件也就是XML文件中,使得更换组件非常简单。
5. IOC的通俗理解
IOC控制反转:创建对象实例的控制权从代码控制剥离到IOC容器控制,实际就是在xml文件中控制,侧重于原理。
DI依赖注入:创建对象实例时,为这个对象注入属性值或其他对象实例,侧重于实现。
spring之AOP
1. 什么是AOP
-- 基本概念 Aspect-Oriented Programming,面向切面编程技术,将应用系统分为两个部分:核心业务逻辑,以及横向的通用逻辑(所谓的方面),例如持久管理。事务管理。安全管理、日志管理和调试管理等。在spring中,允许分离业务逻辑和系统级的服务进行内聚性的开发。应用对象只用完成业务逻辑。
-- AOP和OOP的关系 AOP是对面向对象OOP的有益的补充,也是对OOP的延续,是spring中的重要内容。OOP主要考虑实体、属性、类,研究的是一种静态的领域。OOP考虑的是程序动态运行的过程,针对业务处理过程中的切面进行提取,研究的是动态的领域。
-- AOP的主要功能 主要用于系统级别的功能。例如:日志记录、性能统计、安全控制、事务处理、异常处理等等。
-- AOP的主要意图 将日志记录、性能统计、安全控制、事务处理、异常处理等系统级功能,从业务逻辑中划分出来,通过对这些行为的分离,希望可以将他们独立到非指导性业务逻辑方法当中,进而改变这些行为的时候,不影响业务逻辑代码的处理。也就是说,AOP把常用的服务进行模块化,以声明的方式,将这些组件使用到其他的业务组件当中去。这使得,每一个业务组件只用关心自己的业务逻辑,不用了解常用的服务组件。保证了更高的内聚性。
AOP是软件开发发展中的下一个光环,可以有效防止代码混乱。spring框架是一个轻量级的AOP技术,无需使用预编译器或者其他语言标签,便可以在java代码中使用它。
2. AOP的存在价值
AOP的存在价值系统有很多不同的组件,每一个组件负责特定的功能。我们希望每一个组件,只关心自身的核心功能。
但是系统中会有一些组件,比如日志模块、事务模块、安全模块,会比较频繁地融入到其他核心业务逻辑组件当中去。这些常用的组件会分散到其他多个组件当中。这会导致两个问题:如果这些常用的服务组件经常发生变化,我们需要在多个其他组件之中进行修改。另外,组件代码因为插入了和核心业务无关的其他服务组件,而变得很混乱。
如上图的图1,多个方法都用到了同一个代码段,通过复制粘贴的方式完成这一部分的开发。如果这个代码段需要修改,那么工作是重复而巨大的。
如上图的图2,我们将这个代码段封装成一个方法,三个代码当中只要分别调用这个方法就好了,这时如果需要修改深色代码段,只需要修改一次就好。大大降低了软件后期维护的复杂度。这种方式能够应付大部分应用场景。
但是还有一些特殊的情况,比如,应用需要三个方法彻底与深色方法相分离。在软件开发中,代码是需要经常修改的,客户随时可能提出新的需求。面对需求变更,如果定义一个新的方法,再修改这三个方法,增加新定义的方法工作量也是很大的。 我们希望定义一个方法,无需在三个方法中显示调用,系统能够自动的调用这个方法。实现这种方式的就是AOP技术。
3. AOP的原理剖析
AOP实际上由目标类的代理类实现,包含了目标对象的全部方法。但AOP代理中的方法与目标对象的方法存在着差异,AOP方法在特定的切入点添加了增强处理,并回调了目标对象的方法。
AOP的原理剖析对于AOP编程,需要程序猿参与的有三个部分:
- 定义普通业务组件
- 定义切入点 一个切入点可能会横切多个业务组件。
-
定义增强处理 增强处理,就是在AOP框架在普通业务组件置入的处理动作。
所以,AOP编程的关键:就是定义切入点和定义增强处理。一旦定义了合适的切入点和定义增强处理,AOP框架就会自动生成AOP代理。
AOP的实现原理,简单地说,就是,AOP框架负责动态生成AOP代理类,这个代理类的方法由增强和回调目标对象的方法所组成。
4. AOP的关键概念
spring官方文档对AOP一些关键概念的解释:
- 切面-Aspect 切面,是横切多个类的关注点的模块化。事务管理是J2EE应用程序中横切关系的一个很好的例子。在Spring AOP中,切面是使用常规类(基于模式的方法)或用@aspect注释(@aspectj风格)注释的常规类实现的。
- 连接点-Join Point 连接点,是程序执行期间的一个特定的点,例如执行某个方法或处理异常的时候。在Spring AOP中,连接点总是表示方法的执行。
- 通知-Advice 通知,在特定连接点上的某个方面采取的动作。不同类型的通知包括“arround”、“before”和“after”通知。许多AOP框架,包括Spring,以拦截器为通知模型,在连接点周围维护一串拦截器。
- 切入点-Point Cut 切入点,匹配连接点的谓词。通知与切入点表达式相关联,并在切入点匹配的任何连接点上运行(例如,一个带有特定名称的方法的执行)。切入点表达式与切入点表达式相匹配的概念是AOP的核心,Spring在缺省情况下使用AspectJ切入点表达式语言。
- 引入-Introduction 引入,为一种类型声明额外的方法或字段。Spring AOP允许您向任何通知的对象(即被代理的对象)引入新的接口(以及相应的实现)。例如,您可以使用一个引入来使bean实现一个IsModified接口,以简化缓存。(在AspectJ社区中,引入称为跨类型声明。)
- 目标对象-Target Object 目标对象被一个或多个切面通知,也被称为建议对象。由于Spring AOP是使用运行时代理实现的,所以这个对象将始终是一个被代理的对象。
- AOP代理-AOP Proxy AOP代理,一个由AOP框架创建的对象,目的是实现切面契约(通知方法执行等等)。在Spring框架中,AOP代理将是一个JDK动态代理或CGLIB代理。
- 织入-Weaving 织入,将切面链接到其他应用程序类型或对象之上来,以创建一个被通知的对象。这可以在编译时完成(例如,使用AspectJ编译器),加载时,或者在运行时完成。与其他纯Java AOP框架一样,Spring AOP在运行时进行了织入。
5. AOP的通俗理解
AOP的通俗理解哪里有不对的地方,欢迎大家指正!
网友评论