1. spring框架简介

1.1 spring框架结构


spring框架各个模块说明

  1. 核心容器(实现IoC的重要组件):提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
  2. Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
  3. Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
  4. Spring DAO: JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息*。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
  5. Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
  6. Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
  7. Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

2. IoC(控制反转)

2.1 IoC控制反转和DI依赖注入原理

 Ioc—Inversion of Control,是一种设计思想,意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。把控制权反转交给容器,就是控制反转。这种控制权的使用和实现,可以从以下两个角度来看:

  • 对象的创建(工厂模式):传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建

  • 依赖对象的获取:传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,而IoC另外一个重要特性就是依赖注入(DI),即由容器来帮忙创建及注入依赖对象

ps: IoC和DI很多时候表达的是一件事情——即对象及其依赖的对象交给容器管理其生命周期!

传统管理对象方式图例

使用IoC的设计思想采用容器管理对象

2.2 IoC/DI 带来的好处

IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合 、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也 方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

2.3 实现IoC的对象容器工作流程

  1. 定位:对资源文件(Spring的配置文件是:applicationContext.xml)的定位
  2. 载入解析:将资源文件载入内存,我们需要解析资源文件中的

配置文件中Bean的结构如下:


解析分为三步:

  1. 对bean的id等属性解析;
  2. 对bean中property进行解析,将properties的值取出;
  3. 合并1,2的结果,组成一个完整的数据结构--BeanDefinition(这是spring 容器的定义类),在解析元素过程中没有创建和实例化Bean对象,只是创建了Bean对象的定义类BeanDefinition,将元素中的配置信息设置到BeanDefinition中作为记录,当依赖注入时才使用这些记录信息创建和实例化具体的Bean对象。

注册:将解析完整的数据结构(BeanDefinition)存放在容器中,不能重复。

依赖注入:将IOC容器中存放的数据结构(BeanDefinition),实例化被依赖对象,将依赖关系注入到调用对象中。

3. AOP(面向切面编程)

3.1 AOP思想浅析

AOP是OOP的一个延伸和发展,也是spring另一个非常重要的设计思想。

OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。

这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

总的来说:spring 中ioc技术实现了核心业务逻辑对象之间的解耦,op技术实现的是核心业务逻辑对象与非核心通用服务之间的解耦。例如在一个web应用中,aop将

AOP容器操作示意图
对于放入业务容器的业务颗粒均享有此业务容器的所有通过AOP所具有的服务,并且可以进行相应的配置,哪些业务颗粒享有哪些服务等。

AOP容器是将业务颗粒和服务颗粒组装的过程,业务颗粒和服务颗粒均使用容器,这样可以实现他们之间多对多的关系配置,一个业务可以享用多个服务,一个服务可以被多个业务复用。

3.2 AOP实现(代理模式)

  1. 静态代理:以 AspectJ 为代表使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;优点:性能好
  2. 以 Spring AOP 为代表。其它: Jboss, nanning在运行时借助于 JDK 动态代理、CGLIB 等在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。 性能:低

3.3 AOP操作流程

Spring 允许使用 AspectJ Annotation 用于定义方面(Aspect)、切入点(Pointcut)和增强处理(Advice),Spring 框架则可识别并根据这些 Annotation 来生成 AOP 代理。简单地说,Spring采用运行时生成动态代理的方式来增强目标对象,所以它不需要增加额外的编译,也不需要 AspectJ 的织入器支持。

AOP 代理其实是由 AOP 框架动态生成的一个对象,该对象可作为目标对象使用。AOP 代理包含了目标对象的全部方法,但 AOP 代理中的方法与目标对象的方法存在差异:AOP 方法在特定切入点添加了增强处理,并回调了目标对象的方法。AOP 代理对象的方法 = 增强处理 + 被代理对象的方法

Spring 的 AOP 代理由 Spring 的 IoC 容器负责生成、管理,其依赖关系也由 IoC 容器负责管理。因此,AOP 代理可以直接使用容器中的其他 Bean 实例作为目标,这种关系可由 IoC 容器的依赖注入提供。

AOP 编程,需要手动参与的3 个部分:
1)定义普通业务组件。
2)定义切入点,一个切入点可能横切多个业务组件。
3)定义增强处理,增强处理就是在 AOP 框架为普通业务组件织入的处理动作。

在上面这个业务定义中,不难发现 Spring AOP 的实现原理其实很简单:AOP 框架负责动态地生成 AOP 代理类,这个代理类的方法则由 Advice 和回调目标对象的方法所组成。

总结:AOP代理对象中找到切入点(某个对象),对其加入增强处理(比如自动的写日志这种横向代码)

参考资料:
1.http://www.cnblogs.com/xdp-gacl/p/4249939.html

  1. http://blog.csdn.net/zhaolijing2012/article/details/48132267?utm_source=tuicool&utm_medium=referral