Spring 依赖注入概论_第1页
Spring 依赖注入概论_第2页
Spring 依赖注入概论_第3页
Spring 依赖注入概论_第4页
Spring 依赖注入概论_第5页
已阅读5页,还剩83页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Spring概述,课程目标,Spring的IOCSpring的AOPspring中的事务管理器Spring与struts2集成Spring与hibernate集成SSH集成,一个问题,传统组建调用方式,RegisterActin依赖于UserDAO类。,如果需要进行oralce连接,Action需要进行源码修改,缺陷分析,1无法真正动态加载无法动态替换,替换时必须修改代码,即使应用的是工厂,依然存在代码修改的情况,因为我们必须重新设计工厂。2实例无法共享,多组件无法共享同一实例,因为实例的生命周期是依赖于调用者组件,二者同生共死,即使应用工厂,也是每个实例只为一个客户端使用。3测试困难因为必须包含一个组件的实例,如果实例包含了数据库引用的化,无法离开数据库运行环境。,使用对象必须创建吗,对象创建方式在原始社会,为了使用一个对象,我们曾经采用如下方式:StudentBusinesbusiness=newStudentBusiness();在应用设计模式的思想进行分析以后,我们明白,过去的做法,造成了创建者和使用者责任的无法区分,系统的耦合度过高。于是我们应用工厂进行解耦程序世界进入半现代社会,但是,虽然使用者不再new一个对象了,可是,也不过仅仅是把对象的创建过程封装到了工厂中而已,我们毕竟还是new了一个对象。耦合并没有完全解除。为了使用对象,我们必须要new吗?耦合就没有办法完全解除吗?我们一直在期待!,不new你怎么办,我们可以采用IoC(控制反转)。控制反转:InversionofControl让组件之间的依赖关系通过抽象(接口或抽象类的变量)来建立,在组件运行期间,将组件依赖的实际对象,注入(填充)进来,并由组件内部包含的抽象变量来引用,从而,就可以解藕了.,什么是IOC,IoC就是InversionofControl,控制反转。IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制。,假设我们要设计一个Girl和一个Boy类,其中Girl有kiss方法,即Girl想要Kiss一个Boy。那么,我们的问题是,Girl如何能够认识这个Boy?,常见的MM与GG的认识方式有以下几种,1青梅竹马;2亲友介绍;3父母包办,Boy,publicclassBoyprivateStringname;privateintage;publicBoy()name=dingna;age=10;publicBoy(Stringname)=name;age=10;.,BoyFactory,packagecom.dn.test;publicclassBoyFactorypublicstaticBoycreateBoy(Stringname)returnnewBoy(name);,青梅竹马:,Girl从小就知道自己的Boy。/*第一种方式,自由恋爱publicclassGirl/*第一种方式,自由恋爱Boyb=newBoy(tom);publicvoidkiss()b.kissMe();publicstaticvoidmain(Stringargs)newGirl().kiss();*/,缺点,然而从开始就创建的Boy缺点就是无法在更换。并且要负责Boy的整个生命周期。如果我们的Girl想要换一个怎么办?,亲友介绍:,由中间人负责提供Boy来见面publicclassGirl/*第二种方式,经人介绍*Boyboy;publicGirl()boy=BoyFactory.createBoy(tom);publicvoidkiss()boy.kissMe();publicstaticvoidmain(Stringargs)newGirl().kiss();*/,缺点,亲友介绍,固然是好。如果不满意,尽管另外换一个好了。但是,亲友BoyFactory经常是以Singleton的形式出现,不然就是,存在于Globals,无处不在,无处不能。实在是太繁琐了一点,不够灵活。我为什么一定要这个亲友掺和进来呢?为什么一定要付给她介绍费呢?万一最好的朋友爱上了我的男朋友呢?,父母包办:,一切交给父母,自己不用费吹灰之力,只需要等着Kiss就好了。/*第三种方式:父母包办*publicvoidkiss()ApplicationContextctx=newFileSystemXmlApplicationContext(src/applicationContext.xml);Boyboy=(Boy)ctx.getBean(boy);boy.kissMe();publicstaticvoidmain(Stringargs)newGirl().kiss();*/Well,这是对Girl最好的方法,只要想办法贿赂了Girl的父母,并把Boy交给他。那么我们就可以轻松的和Girl来Kiss了。看来几千年传统的父母之命还真是有用哦。至少Boy和Girl不用自己瞎忙乎了。这就是IOC,将对象的创建和获取提取到外部。由外部容器提供需要的组件。,IoC,是一种模式IoC(InversionofControl)中文译为控制反转,目前Java社群中流行的各种轻量级容器的实现都是以IoC模式作为基础的。控制反转意味着在系统开发过程中,设计的类将交由容器去控制,而不是在类的内部去控类与类之间的关系将交由容器处理,一个类在需要调用另一个类时,只要调用另一个类在容器中注册的名字就可以得到这个类的实例,与传统的编程方式有了很大的不同,”不用你找,我来提供给你”,这就是控制反转的含义。MartinFowler在他的一篇文章中给IoC起了一个更为直观的名字:依赖注射DI(DependencyInjection)。,1.5Spring先睹为快,项目结构,1.5Spring先睹为快,主要代码:Action.javapackagecom.dn.action;importcom.dn.dao.UserDAO;publicclassRegisterActionpublicUserDAOdao;publicvoidexecute()System.out.println(registerActonisgoing.);dao.save();publicUserDAOgetDao()returndao;publicvoidsetDao(UserDAOdao)this.dao=dao;,1.5Spring先睹为快,主要代码:applicationContext.xml,1.5Spring先睹为快,主要代码:Test.javapublicstaticvoidmain(Stringargs)/RegisterActionrigister=newRegisterAction();/rigister.execute();ApplicationContextctx=newClassPathXmlApplicationContext(applicationContext.xml);RegisterActionrigister=(RegisterAction)ctx.getBean(register);rigister.execute();,1.5Spring先睹为快,程序分析我们的所有程序代码中(除测试代码之外),并没有出现Spring中的任何组件。Rigister中的UserDAO对象的值applicationContext.xml动态设置。spring中实现依赖注入的两种方法中,setter方法用得比construtor多,尤其是参数多的时候。construtor是在new的时候注入依赖对象的,而set则相对晚一点,是在set是注入的。(两者都是自动进行的)建议采用面向接口编程,无需知道实现类的具体名称,便于代码重用和细节的隐藏。可以很简单的通过修改配置文件来切换具体的底层实现类。,小结,Spring方式在程序中没有采用new方式Spring中的类由spring系统来生成,程序无需控制。,使用spring来解决DAO由sql变于oracle的方式,增加一个接口IDAO它里面有两个实现UserDAO1UserDAO2一个是mysql的实现,一个是oracle的实现修改actionprivateIDAOdao;在appliationContext.xml文件中增中一个bean,春天的来临,2002最后一场雪以后,RodJohnson结合自己多年的开发经验,撰写了ExpertOne-on-OneJ2EE设计与开发一书,书中对正统J2EE架构的臃肿、低效提出质疑,并阐述新的技术实现以及新的思维模式。引发了人们对正统J2EE的反思。这本书真正地改变了Java世界。翌年春天,基于该书的源代码,形成了一个新的技术架构,这就是Spring。Spring的出现,使得正统J2EE架构一统天下的局面被打破。基于SSH(Struts+Spring+Hibernate)的J2EE架构也逐渐得到人们的认可,并且在大型的项目架构中也逐渐开始应用。这本书也体现了作者对技术的态度:技术的选择应该基于实证或是自身的经验,而不是任何形式的偶像崇拜或者门户之见。,Spring简介,Spring是一个开源的J2EE框架。它作为一个优秀的轻量级的企业应用开发框架,可以大大简化企业应用开发的复杂性,能够创建出松耦合、易测试、易扩展、易维护的Java应用系统,就象春风一样,吹拂着Java大地。特点轻量级:从大小和系统开支上说Spring都算是轻量级的。反向控制:Spring提倡使用反向控制(IoC)来实现松耦合。面向切面:Spring对面向切面编程(AOP)提供了强大的支持,通过将系统服务(如监控和事务管理)从业务逻辑中分离出来,实现了内聚开发。容器:Spring是一个容器,能够装配对象并管理对象的生命周期。框架:Spring实现了把简单的组件组合装配成一个复杂系统的功能。Spring的官方网址:,Spring架构组成,1.1Spring简介,Spring简介(一)Spring的基础思想来源于RodJohnson的一本著名的j2ee书籍:ExpertOne-on-OneJ2EEDesignandDevelopment。在这本书中,RodJohnson列举EJB的种种问题,并提出了相应的解决办法。2003年2月Spring框架正式成为一个开源项目,并发布于SourceForge中。官方网址Spring的核心是个一个轻量级的容器、是一个为软件开发提供全方位支持的应用程序框架。,1.1Spring简介,Spring简介(二)Spring核心技术包括两个方面,一是控制反转(IoC),另一个是面向切面编程(AOP)。Spring的一个重要应用就是实现对struts和hibernate的整合,形成流行的SSH开发架构。Spring囊括了十分丰富的内容,包括表述层、数据层,它提供了许多原来只有EJB才能提供的功能(如声明式式的事务管理),但Spring又无须运行在EJB容器上。无论Spring涉足到哪个领域,都是使用简单的JavaBean,无需实现特殊接口或继承基类,所以在容器外也是可用的,1.1Spring简介,Spring简介(三)Spring与Struts框架,Hibernate框架相对比,他们的不同之处在于:Spring还可以集成其它框架,它是一个“大”框架Spring是专注于企业应用的框架,它所涉及的领域非常之广泛Struts只是专注于实现Web应用程序开发的V、C部分Hibernate只是专注于数据持久层的部分,1.2术语介绍,容器(Container):就是符合某种规范或要求的能够提供一系列服务的管理器,其他人员可以利用容器提供的服务方便的实现某些特殊的功能。例如:web容器,servlet容器。每个容器除了提供自己特殊的服务,如web容器输出HTML文件,servlet容器调用jsp和servlet程序输出动态网页外,还都要实现一些最基本的功能,例如生命周期管理、查询定位、行为配置和扩展支持等。,1.2术语介绍,轻量级(Lightweight):轻量级是相对重量级的容器来说的,Spring的核心包只有约1MB的大小,而使用Spring核心包所需要的资源也是很小的,你甚至可在小型设备中使用Spring的核心包EJB容器就是重量级的,EJB功能全面,但部署复杂,运行缓慢;内在服务多,启动慢;规则多,空间小;难以测试等。为了克服这些缺点,轻量级容器诞生了。它所使用的应用都是可配置的,可选择的,可以去掉那些不需要的组件。在已有的轻量级容器中,绝大多数来自开源社区。,1.2术语介绍,非侵入性(Nointrusive):Spring的目标之一是实现一个非侵入性框架,希望让应用程序几乎感受不到框架的存在,减低应用程序在框架移植时的负担,进一步增加应用程序组件的可重用性。简单地说,使用Spring的话,应用程序中某些组件可以直接拿到另一个应用程序或框架之中直接使用。Struts是一个具有一定侵入性的框架,要实现其Action、ActionForm类,导致严重依赖于Struts,移植困难。EJB更是一个高侵入性的技术。,1.2术语介绍,IoC(InversionofControl):控制反转Spring最重要的概念。使用IOC,你不必自己在程序代码中维护对象的依赖关系,只需在配置文件中加以设定,IOC会自动根据配置来维护对象之间的依赖关系。一个应用程序在使用了IOC后,就不需要再进行对象的创建工作了,而是通过配置文件来描述对象的创建方法、参数以及对象之间的依赖关系,spring会自动的依据对象之间的依赖关系来创建对象。IOC的实现方式有依赖注入和服务定位器两种,Spring采用了DI。依赖注入类型有3种:基于setter方法、基于构造方法、以及基于接口注入。Spring支持前两种。,1.2术语介绍,采用IoC之前采用IoC之前,对象的创建以及对象关系的维护都要由程序员通过硬编码的形式来维护。采用IoC后,对象的创建以及对象关系的维护将由IoC容器来实现,维护的依据是配置文件,程序员直接从容器中取对象就可以了。,1.2术语介绍,采用IoC之后,1.2术语介绍,AOP(Aspect-orientedprogramming):AOP,面向切面编程,是一种编程方法,它和面向对象编程采用的顺序(纵向)编程形成互补,可以解决一些在OOP中无法或很难解决的问题,例如事务、日志、权限等横切性问题,使得OOP集中精力于业务逻辑编程。OOP实现横切性关注点导致代码混乱,开发者必须同时考虑业务逻辑、性能、日志、安全等问题。代码分散,横切性代码散布在各个模块中。AOP将这些代码模块化,然后织入到需要的模块中。过滤器,拦截器都可以理解为一种AOP技术。,2.8JavaWeb技术Spring,采用AOP之前,采用AOP之后,1.2术语介绍,持久层整合:Spring提供对持久层的整合,如对JDBC的使用加以封装与简化,提供事务(Transaction)管理功能,对ORM工具(Hibernate、iBATIS)Spring也提供了整合方案。,1.2术语介绍,Web框架:Spring提供MVCWeb框架解决方案,使用SpringWeb框架的好处是可以善用IoC与AOP的功能,你甚至可以轻松地替换使用不同的View层技术,例如使用JSP、结合Tiles、使用PDF作为展现给使用者的画面技术。也可以将自己所熟悉的Web框架与Spring整合,例如Struts、JSF等,都可以与Spring整合,而适用于当前所进行的应用程序。,1.3Spring框架图示,1.4Spring包的目录结构,Spring架构组成(一),核心容器:核心容器提供Spring框架的基本功能,为Spring提供了基础服务支持,核心容器的主要组件就是BeanFactory,BeanFactory是所有基于Spring框架系统的核心,通过BeanFactory,Spring使用工厂模式来实现IoC,将应用程序的配置和依赖关系与实际的应用程序分离开来.Spring之所以称为容器,就是由于BeanFactory的自动装备和注入。,Spring架构组成(二),ApplicationContext(上下文)Spring上下文是由一个配置文件,这个配置文件就是applicationContext.xml文件,它向Spring框架提供上下文信息。BeanFactory使spring成为容器,上下文模块使Spring成为框架,这个模块对BeanFactory进行了扩展,添加了对I18N,系统生命周期事件以及验证的支持。这个模块提供了许多企业级服务,例如邮件服务,JNDI访问,EJB集成,远程调用以及定时服务,并且支持与模板框架的集成。,Spring架构组成(三),SpringAOP:AOP面向切面编程。该模块将AOP编程功能集成到了Spring框架中。这样,凡是Spring框架管理的任对象都可以很容易地支持AOP。该模块为应用程序中基于Spring管理的对象提供了事务管理服务。这个模块由于使用了AOPAlliance的API,所以,可以和其他AOP框架互通,AOPAlliance是一个开源项目目的是促进AOP的使用,并且通过定义一套通用的接口和组件来确保不同的AOP之间达到互通性。,Spring架构组成(四),SpringDAO:这个模块封装了数据库连接的创建,语句对象生成,结果集处理,连接关闭等操作,而且重构了所有数据库系统的异常信息,用户不再需要处理数据库异常了。在这个模块中,利用了Spring的AOP模块完成了为系统中对象提供事务管理的服务。,Spring架构组成(五),SpringORM:Spring没有实现自己的ORM方案,而是为当前主流的ORM框架预留了整合接口,包括hibernate,JDO。所有这些都遵从Spring的通用事务和DAO异常层次结构。,Spring架构组成(六),SpringWeb模块:Web上下文模块建立在应用程序上下文模块之上,为基于Web的应用程序提供了上下文。所以,Spring框架支持与JakartaStruts的集成。Web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。,Spring架构组成(七),SpringMVC框架:MVC框架是一个全功能的构建Web应用程序的MVC实现。通过策略接口,MVC框架变成为高度可配置的,MVC容纳了大量视图技术,其中包括JSP、Velocity、Tiles、iText和POI。,BeanFactory树,BeanFactory是Spring中采用工厂设计模式的一个核心接口,该接口的实现类负责创建和分发Bean。在Spring中由几种BeanFactory的实现类,其中最常用的是:XmlBeanFactory,Spring的程序的运行流程,从上面的例子中我们可以看出Spring程序工作的一般流程如下:1:初始化Spring的Bean工厂ApplicationContextctx=newClassPathXmlApplicationContext(applicationContext.xml);2:通过Bean工厂获得Bean的实例Ctx.getBean(“register”);3:调用Bean实例方法,完成业务处理r.execute();4:销毁Spring的Bean工厂(Spring负责)!,Bean的初始化过程,Spring的bean初始化过程一共有14个步骤,并且严格按顺序执行.这其中,只有第一,第二和13个步骤是必要的,其他步骤,都需要在bean中引入Spring的接口,所以,一般而言,不需要使用.必要步骤1.根据xml中对bean的定义,创建一个bean的实例,并传入必要的构造方法参数.2.根据XML中对bean的定义完成依赖注入13.如果为bean定义了init-method方法,调用改方法完成初始化工作.在配置文件中为bean指定init-method属性,属性名为要调用的方法名称.名称不限定,可以私有.注意:Spring下,bean是先装配后初始化的.因为初始化过程可能用到注入的实际对象,关于Bean的疑问,提问?Spring的工作流程是围绕怎样得到Bean和怎么使用Bean来展开的,即使BeanFactory的创建也可以看作是Bean使用过程中的附属产品,那么,Spring中的Bean到底是什么东西?,再论Bean,JavaBean原始形态是一种符合特定规范的java对象,有无参构造器,通过get/set提供外界对私有属性的访问,是最简单最基本的java组件,即可被用作数据承载的载体即VO,也可以用来执行业务逻辑。随着编程思维以及现实环境的发展,JavaBean的规范在实际应用中日趋模糊,日渐与POJO融合。在Spring中,大力推荐使用的JavaBean,实际上就是POJO,凡是可以被实例化或是可以被JNDI获得的对象,都可以被Spring容器管理,都是Bean,ApplicationContext,虽然BeanFactory是Spring中很重要的一个概念,但是在大多数情况下,我们并不是直接应用它,而是应用BeanFactory的子接口ApplicationContext接口。,实现类的应用,ApplicationContext有很多实现类,但只需掌握常用的三个:ClassPathXmlApplicationContext:从类路径下的XML文件中载入上下文定义信息FileSystemXmlApplicationContext:从文件系统路径下的XML文件中载入上下文定义信息XmlWebApplicationContext:通过ContextLoaderListener从内部导入context文件,ApplicationContext应用示例,从文件系统路径下导入配置文件FileSystemXmlApplicationContext实例从类路径下导入配置文件ClassPathXmlApplicationContext实例,ApplicationContext与BeanFactory,BeanFactory采用延迟加载Bean,直到第一次使用getBean()方法获取Bean实例时,才会创建Bean。ApplicationContextApplicationContext在自身被实例化时一次完成所有Bean的创建。区别在服务启动时ApplicationContext就会校验XML文件的正确性,不会产生运行时bean装配错误。BeanFactory在服务启动时,不会校验XML文件的正确性,获取bean时,如果装配错误会,马上就会产生异常,再论软件组件调用,一如我们此前讨论传统组件调用方式存在很多缺陷。控制权在应用程序本身,程序的流程完全由开发者自己控制。在这种情况下,如果系统中有大量组件,并且其生命周期和依赖关系由组件自己来维护,就会大大增加系统的复杂程度,而且会造成组件之间的紧耦合,不利于系统的维护和测试。,再论软件组件调用(下),经过上面的分析我们可以发现,问题的核心归结为:如何组装大量的Bena,使之相互配合完成复杂的工作,即便于维护又有利于测试。以上问题的产生,就在于bean的依赖关系管理不恰当。解决之道就是应用IoC,那么什么是IoC那。,再论IoC,IoC的直译是控制反转。在IoC模式下,控制权限从应用程序转移到了IoC容器中。组件不是由应用程序负责创建和配置,而是由IoC容器负责。使用IoC的情况下,对象是被动地接收依赖类而不是主动地查找,对象不是从容器中查找他的依赖类,而是容器在实例化对象时,主动地将他所依赖(一般依赖关系,对象包含)的对象注入给他。应用程序只需要直接使用已经创建并且配置好的组件即可,而不必自己负责创建和配置。在实际的工作中人们发现使用IoC来表述这种机制,并不是很准确甚至有些晦涩,于是引发了另外一个概念,DI(依赖注入)注意:把什么转移了,控制权到底是什么关系?,依赖注入(上),目前人们认为使用依赖注入(DI)来阐述IoC更为合适。而事实上早在2004年初,MartinFowler在他的站点谈论控制反转时曾提问:“问题在于,它们转变的是什么方面的控制?”。Fowler建议重命名该原则(或至少给它一个更加明确的名称),并开始使用“依赖注入”这个术语。,解析IoC和DI(上),IoC解析IoC(控制反转)是Spring容器的内核,AOP以及声明式事务都是在此之上完成的.IoC包括两层含义1.控制;2反转.关键的问题在于他把什么东西的控制给反转了.控制指组件之间的调用关系由程序自身控制(从而造成了紧耦合).反转是说,将这种调用关系的控制权从程序中异除,并交给第三方管理.也就是组件的调用关系由程序自身管理转变为第三方管理.是组件依赖关系的控制权进行了反转对于上述机制,应用IoC来描述并不准确,而且有些晦涩.,解析IoC和DI(下),DI解析之所以会产生组件调用,是为了获取被调用组件的功能,调用者将自己应该做的事情,委派给了被调用的对象.也就是说,调用者要完成自身的任务,必须依赖被调用的对象.这种关系实际上就是一般依赖关系(通俗点说,就是一个组件内部包含另外一个组件的实例,把该自己干的事交给自己包含的组件去完成),因此IoC所表述的机制,实际上就是将调用者对接口实现类的依赖关系,从程序中移除,转交第三方管理实例,并且,由第三方在运行期间将调用者依赖的具体类填充进来.也就是说组件之间的依赖关系,是在程序运行期间由第三方来管理的.这个就是依赖注入的概念(DI).基于上述分析,DI比IoC更准确.实际上就是将调用者为完成功能所依赖的实现类,在程序运行期间,由容器自动填充给调用者.这个就是依赖注入的核心思想.在依赖注入的应用中,组件并不关心被注入的对象是谁,只关系这个对象能完成的功能.也就是这个对象是那个接口的具体类实例.,简单的约定,我们在讲课时一律采用“依赖注入”这个概念,而提到容器时,我们采用“IoC容器”一词,因为他更加流行。,依赖方式比较,依赖注入的三种方式,构造子注入构造注入指的就是在接受注入的类中定义一个构造方法,并在参数中定义需要注入的元素。设置属性注入(建议使用)Set注入指的就是在接受注入的类中定义一个Set方法,并在参数中定义需要注入的元素。接口注入(不建议使用)接口注入指的就是在接口中定义要注入的信息,并通过接口完成注入。,属性可以有几种方式,IntStringStringListSetMapDate自定义类型,基本类型注入,基本数据类型的注入在配置文件中直接注入即可,步需要数据类型,IoC容器会自动的根据bean中属性的类型,完成类型转换,并赋值。注入语法如下第一种:其中id表示bean在整个工程中的唯一标识,class表示该标识的引用类第二种写法

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论