对Spring的IoC和DI最生动的解释

一、Spring IOC  IoC与DI

         首先想说说IoC(Inversionof Control,控制倒转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来讲,就是由spring来负责控制对象的生命周期和对象间的关系。这是什么意思呢,举个简单的例子,咱们是如何找女友的?常见的状况是,咱们处处去看哪里有长得漂亮身材又好的mm,而后打听她们的兴趣爱 好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,而后嘿嘿……这个过程是复杂深奥的,咱们必须本身设计和面对每一个环节。传 统的程序开发也是如此,在一个对象中,若是要使用另外的对象,就必须获得它(本身new一个,或者从JNDI中查询一个),使用完以后还要将对象销毁(好比Connection等),对象始终会和其余的接口或类藕合起来。java

  那么IoC是如何作的呢?有点像经过婚介找女友,在我和女友之间引入了一个第三者:婚姻介绍所。婚介管理了不少男男女女的资料,我能够向婚 介提出一个列表,告诉它我想找个什么样的女友,好比长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,而后婚介就会按照我 们的要求,提供一个mm,咱们只须要去和她谈恋爱、结婚就好了。简单明了,若是婚介给咱们的人选不符合要求,咱们就会抛出异常。整个过程再也不由我本身控 制,而是有婚介这样一个相似容器的机构来控制。Spring所倡导的开发方式就是如此,全部的类都会在spring容器中登记,告诉spring你是个什 么东西,你须要什么东西,而后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其余须要你的东西。全部的类的建立、销毁都由 spring来控制,也就是说控制对象生存周期的再也不是引用它的对象,而是spring。对于某个具体的对象而言,之前是它控制其余对象,如今是全部对象 都被spring控制,因此这叫控制反转。若是你还不明白的话,我决定放弃。web

       IoC的一个重点是在系统运行中,动态的向某个对象提供它所须要的其余对象。这一点是经过DI(Dependency Injection,依赖注入)来实现的。好比对象A须要操做数据库,之前咱们老是要在A中本身编写代码来得到一个Connection对象,有了spring咱们就只须要告诉spring,A中须要一个Connection,至于这个Connection怎么构造,什么时候构造,A不须要知道。在系统 运行时,spring会在适当的时候制造一个Connection,而后像打针同样,注射到A当中,这样就完成了对各个对象之间关系的控制。A须要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3以后一个重要特征是反射(reflection),它容许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是经过反射来实现注入的。关于反射的相关资料请查阅java doc。正则表达式

 

        IoC是一个很大的概念,能够用不一样的方式来实现。主要的实现形式有两种:spring

依赖查找:容器提供回调接口和上下文环境给组件。EJB和Apache Avalon都是使用这种方式。数据库

依赖注入:组件不作定位查询,只是提供普通的Java方法让容器去决定依赖关系。容器全权负责组件的装配,它会把符合依赖关系的对象经过JavaBean属性或者构造子传递给须要的对象。经过JavaBean属性注射依赖关系的作法称为设值方法注入(SetterInjection);将依赖关系做为构造子参数传入的作法称为构造子注入(ConstructorInjection)。编程


spring_2.jpg


二、Spring AOP

2.1 面向切面编程基础

  一般,系统由不少组件组成,每一个组件负责一部分功能,然而,这些组件也常常带有一些除了核心功能以外的附带功能。系统服务如日志、事务管理和安全常常融入到一些其余功能模块中。这些系统服务一般叫作交叉业务,这是由于它们老是分布在系统的不少组件中。经过将这些业务分布在多个组件中,给咱们的代码引入了双重复杂性。安全

  (1) 实现系统级业务的代码在多个组件中复制。这意味着若是你要改变这些业务逻辑,你就必须到各个模块去修改。就算把这些业务抽象成一个独立模块,其它模块只是调用它的一个方法,可是这个方法调用也仍是分布在不少地方。架构

  (2) 组件会由于那些与本身核心业务无关的代码变得杂乱。一个向地址录中添加条目的方法应该只关心如何添加地址,而不是关心它是否是安全或支持事务的。框架

  此时,咱们该怎么办呢?这正是AOP用得着的地方。AOP帮助咱们将这些服务模块化,并把它们声明式地应用在须要它们的地方,使得这些组件更加专一于自身业务,彻底不知道其它涉及到的系统服务。模块化

  这里的概念切面,就是咱们要实现的交叉功能,是应用系统模块化的一个方面或领域。切面的最多见例子就是日志记录。日志记录在系统中处处须要用到,利用继承来重用日志模块是不合适的,这样,就能够建立一个日志记录切面,而且使用AOP在系统中应用。下图展现了切面应用方式

 

图表 1 应用切面

  其中,通知Advice是切面的实际实现。链接点Joinpoint是应用程序执行过程当中插入切面的地点,这个地点能够是方法调用,异常抛出,甚至能够是要修改的字段,切面代码在这些地方插入到你的应用流程中,添加新的行为。切入点Pointcut定义了Advice应该应用在那些链接点,一般经过指定类名和方法名,或者匹配类名和方法名式样的正则表达式来指定切入点。

2.2 AOP在Spring中的实现

  基于AOP,业界存在各类各样的AOP实现,好比,JBoss AOP、Spring AOP、ASPectJ、AspectWerkz等。各自实现的功能也不同。AOP实现的强弱在很大程度上取决于链接点模型。目前,Spring只支持方法级的链接点。这和一些其余AOP框架不同,如AspectJ和JBoss,它们还提供了属性接入点,这样能够防止你建立特别细致的通知,如对更新对象属性值进行拦截。然而,因为Spring关注于提供一个实现J2EE服务的框架,因此方法拦截能够知足大部分要求,并且Spring的观点是属性拦截破坏了封装,让Advice触发在属性值改变而不是方法调用上无疑是破坏了这个概念。

  Spring的AOP框架的关键点以下:

  (1)Spring实现了AOP联盟接口。在Spring AOP中,存在以下几种通知(Advice)类型

  Before通知:在目标方法被调用前调用,涉及接口org.springFramework.aop.MethodBeforeAdvice;

  After通知:在目标方法被调用后调用,涉及接口为org.springframework.aop.AfterReturningAdvice;

  Throws通知:目标方法抛出异常时调用,涉及接口org.springframework.aop.MethodBeforeAdvice;

  Around通知:拦截对目标对象方法调用,涉及接口为org.aopalliance.intercept.MethodInterceptor。

  (2)用Java编写Spring通知,并在Spring的配置文件中,定义在什么地方应用通知的切入点。

  (3)Spring的运行时通知对象。代理Bean只有在第一次被应用系统须要的时候才被建立。若是你使用的是ApplicationContext,代理对象在BeanFactory载入全部Bean的时候被建立。Spring有两种代理建立方式。若是目标对象实现了一个或多个接口暴露的方法,Spring将使用JDK的java.lang.reflect.Proxy类建立代理。这个类让Spring动态产生一个新的类,它实现所需的接口,织入了通知,而且代理对目标对象的全部请求。若是目标对象没有实现任何接口,Spring使用CGLIB库生成目标对象的子类。在建立这个子类的时候,Spring将通知织入,而且将对目标对象的调用委托给这个子类。此时,须要将Spring发行包lib/cglib目录下的JAR文件发布到应用系统中。

2.3 Spring AOP的优点

  借助于Spring AOP,Spring IoC可以很方便的使用到很是健壮、灵活的企业级服务,是由于Spring AOP可以提供以下几方面的优点:

  (1)容许开发者使用声明式企业服务,好比事务服务、安全性服务;EJB开发者都知道,EJB组件可以使用J2EE容器提供的声明式服务,可是这些服务要借助于EJB容器,而Spring AOP却不须要EJB容器,借助于Spring的事务抽象框架就能够这些服务。

  (2)开发者能够开发知足业务需求的自定义切面;

  (3)开发Spring AOP Advice很方便。由于这些AOP Advice仅是POJO类,借助于Spring提供的ProxyFactoryBean,可以快速的搭建Spring AOP Advice。

三、结语

  本文详细阐述了Spring背后的IoC原理和AOP技术,以实际成功项目为背景,抽取简短片段,展现了Spring架构J2EE应用系统的原理。SpringIoC借助于依赖注入机制,减轻了组件之间的依赖关系,同时也大大提升了组件的可移植性,组件获得了更多的重用机会。借助于SpringAOP,使得开发者能声明式、基于元数据访问企业级服务,AOP合理补充了OOP技术,Spring AOP合理地补充了SpringIoC容器。Spring IoC与SpringAOP组合,使得Spring成为成功的J2EE架构框架,并能与标准的EJB等标准对抗,EJB再也不是必需品。Spring已经冲入了J2EE的核心,将引领整个J2EE开发、架构的方向。

相关文章
相关标签/搜索