三大框架spring3.0上课提纲_第1页
三大框架spring3.0上课提纲_第2页
三大框架spring3.0上课提纲_第3页
三大框架spring3.0上课提纲_第4页
三大框架spring3.0上课提纲_第5页
已阅读5页,还剩27页未读 继续免费阅读

付费下载

下载本文档

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

文档简介

Spring3.0框框架需求分问题描述:编码依赖问publicclassStudentActionpublicclassStudentAction privateStudentServicestudentService=privateStudentpublicStudentgetStudent()return}publicvoidsetStudent(Studentstudent)this.student=}publicStringsave(){return"success";}}同样在业务逻辑层调用数据层中,也会出现如下问题publicpublicclassStudentServiceimplimplementsStudentService 层也要切换,但是目前new之后不方便修privateStudentDaostudentDao=newpublicvoidsave(Studentstudent){}}以上代码是有问题的,即在控制层中依赖了具体的业务逻辑层在业务逻辑层中依赖了具体的数据层.这样就和具体的实现类耦合在了一起也没有发挥面向接口编程的作用.如果要更换(比如要换成StudentDaoOracleImpl需要修改源代码,但是项目很多模块都需要同时修改,这样会非常麻烦.class文件,覆盖原来的文件.不利于项目的后期,而且项目与项目之间的依赖隐藏在了代码中.也不适合全局把握正个项目,因此性和二次开发比较麻烦解决方案1:工厂模可以使用抽象工厂,StudentDaoStudentService的实现在在工厂中生成,而工厂可以根据配置文件的指定类型,来创建不同的对象,而且工厂本身一般是不变的.从而降低了对可以变的业务逻辑类的依赖,接近的软件的设计目标”高内聚,低耦合”publicclassStudentActionpublicclassStudentAction依赖具体的对象,改为依赖工厂而工厂创建的路径来自具体的配置文件,所以灵活必须 privateStudentServiceprivateStudentpublicStudentgetStudent()return}publicvoidsetStudent(Studentstudent)this.student=}publicStringsave(){return"success";}}业务逻辑层→抽象工厂→数据publicpublicclassStudentServiceImplimplementsStudentServiceprivateStudentDaopublicvoidsave(Studentstudent){}}个实现类,只需要修改配置文件就可以了,注意这里只是降低了层与层之间的复杂度,并没有让耦合,实际上层与层是不可能没有耦合的,我们学框架的目的就是要找到变的部分,OK了,不需要修改代码本身建的时候有些类需要初始化操作,有些又不需要初始化数据…..这又怎么办呢?那就要再完善一下这个工厂类了,或者多创建一些工厂了.让工厂可以处理这些问题,但是我们自己实解决方2:IOC依赖注所谓依赖注入就是指在运行期,由外部配置文件动态地将本身所依赖对象通过set方法注入到组件中,我们只需要用即可,而不需要在去管理对象的创建和销毁我们期望的代publicpublicclassStudentAction//privateStudentServicepublicvoidsetStudentService(StudentServicestudentService)this.studentService=}privateStudentpublicStudentgetStudent()return}publicvoidsetStudent(Studentstudent)this.student=}publicStringsave(){return"success";}}publicpublicclassStudentServiceImplimplementsStudentService//privateStudentDaopublicvoidsave(Studentstudent){}}问题描述:编程式事publicpublicvoidsave(StudentSession//手动控制的事务称为编 try}}catch(HibernateExceptione){}}以上代码是有问题的,红色的部分,每次只要有数据修改操作的时候则都要编写,要的是这些代码与方法的功能本身又没有紧密的联系.而且基本每个模块都有,重复的代码大大降低了我们的效率和增加了的成本,解决方案1:模类,来完成Session事务的提交、回publicclass implementsSessionprivateSessionsession=null;publicSession (Sessionsession){this.session=}publicvoidbegin(){}publicvoidrollback(){}publicvoidsave(Studentstudent)try}catch(Exceptione)}finally}}publicvoidcommit(){}}:publicpublicvoidsave(StudentHibernateSessionFactory返回的是session的 //的save中调用了begincommit或者} .而且 但是我们的事务基本所有的业务逻辑模块都有.}解决方案2:AOP式事Spring3.0介Spring主要功能介绍Spring的IOC容器包含并管理应用对象的配置和生命周期,你可以配置你的每个bean如何被创建,也可以配置每个bean是只有一个实例,还是每次需要时都生成一SpringAOP提供了很多基础但是与业务逻辑无关的功能,比如:事务管理、与持久Spring还提供了自己的MVC实现,和 te来简化数据操Spring功能结构Spring的好降低组件之间的耦合度,实现软件各层之间的解耦容器提供了AOP技术,利用它很容易实现如权限、运行期等功能容器提供的众多辅作类,使用这些类能够加快应用的开发,如:JdbcTem Spring对于主流的应用框架提供了集成支持集成HibernateJPA等,实现框架之间的无缝集成,这样更便于应用的开发SpringSpring资源地Spring框架的主页:Spring框架地址: oSpring开发环境SpringJarSpirng3-AOPAOP功能,Spring3-CoreIOC功能,Spring3-Persistence-JDBC:SpringJDBCSpring配置文件时,不能出现帮助信息解决方法1:让机器上网,eclipse会自动从网络上schema文件并缓存在硬盘上2:schema文件,方法如下:1:windows→preferences→myeclipse→filesandeditors→xmlxmlcatalog2:点"add",在出现的窗口中的KeyType中选择URI,在location中选"Filesystem",spring解压的dist/resourcesspring-beans-3:回到设置窗不要急着关闭窗口,应把窗口中的KeyType改为Schemalocation,Key改为第一Spring程序(IOC解决编码依赖"""applicationContext.xml取代了前面的properties配置文件<bean 指向另一个id此处说明studentService依赖studentDaostudentDao属性是私有的,必须通过set方法注入<propertyname="studentDao"ref="studentDao"配置studentDaoclass是具体的业务逻辑bean<beanid="studentDao" .ssh.b.StudentDaoImpl"publicpublicclass_IOCTestpublicvoidResourceSpringResourceresource=new 建BeanFactorybeanFactory=newgetBean通过name和id去查找实例化的对象,通过Spring容器拿出来的对Studentstudent=newStudent("test",13);}}Spring来管理Action<beanSpring来管理Action<beanid="studentAction"action在创建的时候会把service通过set<propertyname="studentService"ref="studentService"@Test@Test测试Spring管理Action-->Service--publicvoidtest02(){Resourceresource=newBeanFactorybeanFactory=newStudent应该通过前台传入,Studentstudent=newStudent("test2",13);}}Spring的依赖注入功能,Spring的配置文件,y来获取想要的Ben对象,代码中只声明了一个接口类型例如、o这样大大提高了代码的灵活性(消除了编译时依赖,让运行时依赖具体的接口类型,而且以后可以动态变化g给OC功能Resource几种方classpathTomcatapplication配置文件,必@Test测试获取Resourcepublic@Test测试获取Resourcepublicvoidtest03()throwsException{Resourceresource=null;BeanFactorybeanFactory=null;//resource=newClassPathResource("applicationContext.xml");beanFactory=newXmlBeanFactory(resource);//通过文 beanFactory=newXmlBeanFactory(resource);}org.springframework.core.io.Resourceresource=null;BeanFactoryApplicationContext的比ApplicationContextBeanFactoryBeanFactoryBean容器,ApplicationContextApplicationContextBeanFactory,如它可以加载外部的资源文件、可以自AOP切面........classpathTomcatapplication配置文件,必@Test测试Applicationpublic@Test测试Applicationpublicvoidtest04()throwsException{ApplicationContextcontext=new}://必须放到web环境下执行下面的语句SpringIOC详解(重点Bean的三种方<beanid="studentDao" .ssh.c.StudentDaoImpl"<beanid="studentDao" .ssh.c.StudentDaoImpl" factory-method="getBean"publicpublicclassStudentDaoFactorypublicstaticStudentDaogetBean(){ StudentDaoImplimpl=newreturn}}factory-beanref一个普通工厂<beanid="studentDao"factory-bean="studentDaoFactory"method="getBean" .ssh.c.StudentDaoFactory"publicvoid}Bean的生命周getBean()时才生成实例)单例模式+publicvoidpublicvoidtest02(){ApplicationContextcontext=new} 单例模式+懒汉式创建(用的时候在创建)注意:<bean<beanid="studentDao"init="true".ssh.c.StudentDaoImpl" bean<beans<beansdefault-lazy-init="true"SingletionSpring容器管理的都是业务逻辑类,因为只有业务逻辑类才会经常变化.业务逻辑类尽量避免设计全局变量,Singletion模式可能会出现问题,90%的时候业务逻辑类饿汉模式即可,也就是项目启动的时候初始化Action必须是多例的,所以要配置prototype属性,<beanid="studentAction" Action必须是多例的,所以要配置prototype属性,<beanid="studentAction" <!--studentService是否为多例,决定studentServicescope<propertyname="studentService"ref="studentService"@Test@Test//测试actionscope="prototype"publicvoidtest03(){ApplicationContextcontext=new }Prototypescopeprototype则默认是懒汉模式,因为多例在运行时候创建是没有意义的.Spring不负责prototype的销毁.换句话来说,Spring把创建和实体类,Spring中.S2SHAction依赖的实体类还是要通过Struts器赋值,实体类经常是通过程序赋值和而非依赖注入赋值Bean的初始化,和销毁方publicpublicvoid }publicvoid }@Test//测试@Test//测试initpublicvoidtest04(){ClassPathXmlApplicationContextcontext=new }中default-init-method="init"default-destroy-Bean的周期总ClassPathXmlApplicationContextclose()destory方法ApplicationContextclose()方法,需要强转为具体的实现类才可以调用singleton时才会有效)依赖注入的两种Set注<bean<bean.ssh.c.StudentServiceImpl"lazy-<propertyname="studentDao"ref="studentDao"<beanid="studentDao" 构造注通过参数编号指定第一个参数编号为0<beanid="student" <constructor-argindex="1"value="admin"<constructor-argindex="0"value="1"<constructor-argindex="2"value="19"<constructor-argname="sname"value="admin"<constructor-argname="sid"value="1"<constructor-argname="sage"value="19"<beanid="student"复杂类型注向集合注publicpublicclassCollectionTestprivateString[]SetprivateSet<String>ListprivateList<Date>MapprivateMap<String,Student>PropertiesprivatePropertiespublicList<Date>getLists()return}publicvoidsetLists(List<Date>lists)this.lists=}publicMap<String,Student>getMaps()return}publicvoidsetMaps(Map<String,Student>maps)this.maps=}publicString[]getStrs()return}publicvoidsetStrs(String[]strs)this.strs=}publicSet<String>getSets()return}publicvoidsetSets(Set<String>sets)this.sets=}publicPropertiesgetPros()return}publicvoidsetPros(Propertiespros)s=}}<beanid="collectionTest"<beanid="collectionTest" <property<propertydate为日期bean的id<ref<property<property<entrykey="a"value-ref="student"<property<prop<prop<beanid="date"class="java.util.Date"加载外部资 <property,<!--配置文件相同的时候后面的会覆盖前面的<context:property-ceholder>加 由于Property SpringStruts整SpringAction,Action→Service→Dao之间的解耦整合方1:ActionSpring容publicclasspublicclassStudentAction{ApplicationContextcontext=new//privateStudentService通过set方式,publicvoidsetStudentService(StudentServicestudentService)this.studentService=}},了大量的系统资源,其实Spring配置文件只需要加载一次即可,存放到项目的公共区域Application内置对象中,bean的时候获取即可整合方2:Spring来管Spring配置文件<context- Springstruts2-spring-plugin-.jarSpring<!--重新设置了创建Action的工厂类,此类会到Spring容器中取创建--<beantype="com.opensymphony.xwork2.ObjectFactory"class="org.apache.struts2.spring.StrutsSpringObjectFactory"/><!--MaketheSpringobjectfactorytheautomaticdefault-<constantname="struts.objectFactory"value="spring"<actionname="studentAction"class="studentAction"StrutsAction<actionname="studentAction"class="studentAction"设计模模式介模式即Pattern常用的设计模式之一.模式的主要作用是为其他对;()角色:角色内部含有对真实的,从而可以在任何时候操作真实对象角色提供一个与真实角色相同的接口,以便可以在任何时;某个操作,而不是单纯地将调用传递给真实对象;基于接口的静类,来完成Session事务的提交、回publicclass implementsSessionprivateSessionsession=null;publicSession (Sessionsession){thisthis.session=}publicvoidbegin(){}publicvoidrollback(){}publicvoidsave(Studentstudent)try}catch(Exceptione)}finally}}publicvoidcommit(){}}基于继承的静classclasspublicvoidSystem.out.println("-----真实的业务逻 }}publicclassSonextendsFather{publicvoidtest()System.out.println("----执行某些代 System.out.println("----执行某些代 }publicstaticvoidmain(String[]args){Sonson=newSon();}}静态总口或者是继承相同父类,只能某种类型的对象,静态存在一个问题:当我们在被的类中增加了一个方法类中也要增加相应方法,性比较,动动态介绍在运行的时候通过被类的特征(获取被类的接口、类型等)来动态创建对象.这种机制称为动态,可以解决静态范围有限制,难的缺点.动态有基于JavaJDK面向接口的方式和基于继承原理的CGLIB方式APIpublicstaticObject Class<?>[]interfaces,InvocationHandlerh)publicstaticObject Class<?>[]interfaces,InvocationHandlerh)throws返回一个指定接口 类实例,该接口可以将方法调用指派到指定的调用处理程序 publicinterfacepublicinterfaceInvocationHandler是实例的调用处理程序实现的接口 进行编码并将其指派到它的调用处理程序的invoke方法Object ,Methodmethod,Object[]在实例上处理方法调用并返回结案例演*演示基于JDK*Subject为*类,根据此类的信息通类publicclassSubjectimplementsISubjectpublicvoidtest()System.out.println("-----真实的业务逻 }publicStringtest2(intage,Stringname){ 为:"+age+" 为:"+name);return"test2";}publicstaticvoidmain(String[]args){ISubjectsubject =(ISubject) .getClassLoader(),newInvocationHandler()

publicObject ,Object[]param)throwsThrowable采用,动态生成 对象 类的每个方法都会动跳转到此方法(invoke)中直接 )会死循环因 .toString()又会直接进行invoke()方中final的,不能被重

但是可 .getClass(),因为此getClassmethod:真实的业务逻辑方法,可以通过invoke调用param:当前method 类为为

System.out.println(" 类的业务逻辑方法为:"if(param!=null)System.out.println("当前业务逻辑方法的参for(Objecto:param){}}return} .test2(1,}}}类publicstaticObject Instance(ClassLoaderClass<?>[]interfaces,InvocationHandlerh)throws{nullif(h==null)thrownew}//根据传入了类加载器,接口返回 类的ClassClasscl=get Class(loader,interfaces);try{//privatefinalstaticClass[]constructorParams//{InvocationHandler.classConstructorcons=//通过构造方法创建 类,并且把h传入到 类理有h而且调用 类的每一个方法都会跳转到h.invoke中)return(Object)cons.newInstance(newObject[]{h}Instance类publicstaticObject Instance(ClassLoaderClass<?>[]interfaces,InvocationHandlerh)throws{nullif(h==null)thrownew}//根据传入了类加载器,接口返回 类的ClassClasscl=get Class(loader,interfaces);try{//privatefinalstaticClass[]constructorParams//{InvocationHandler.classConstructorcons=//通过构造方法创建 类,并且把h传入到 类理有h而且调用 类的每一个方法都会跳转到h.invoke中)return(Object)cons.newInstance(newObject[]{h}Instance源码如下使用实现Session事务提publicstaticSessiongetSession()throwsHibernateException{Sessionsession=(Session)threadLocal.get();ifpublicstaticSessiongetSession()throwsHibernateException{Sessionsession=(Session)threadLocal.get();if(session==null||!session.isOpen())if(sessionFactory==null)}session=(sessionFactory!=null):}return new}实现不同接口类型的StudentSerive,GradeService*类,功publicclassMyInvocationHandlerimplements{//可 任何的类型,这些类型只 的功能相同就可以使用同一类privateObject//通过构造方法把 对象传入其publicMyInvocationHandler(Object}//权限验证的方法,publicvoidSystem.out.println("----权限验证功 }//日志方法,publicvoidSystem.out.println("-----日志功 } publicObjectinvoke(Object ,Methodmethod,Object[]throwsThrowable{Objectobj=null;obj=method.invoke(object,//如果满足条件,}else////obj=method.invoke(object,//}return}}动态总结JDK的动态有个缺点,那就是不能对类进行,只能对接口进行,想象一下如果项目做二次升级,则并不是前面的业务逻辑类都采用了面向接口编程,那么将无法CGLib动态介基于CGLib的实现:CGLIB是一个开源的动态框架,它的出现补充了自带的不能对类实现动态的问题classclasspublicvoidSystem.out.println("-----真实的业务逻 }}publicclassSonextendsFather{publicvoidtest()System.out.println("----执行某些代 System.out.println("----执行某些代 }publicstaticvoidmain(String[]args){Sonson=newSon();}}----执行某----执行某些代码----执行某些代码子类继承了父类的方法,在子类中实现功能:但这种方式的缺点更明显,那就是只能对BusinessProcessImpl进行,与包装的模式相比大大缩小了范围,但是如果我们能根据父类动态的生成子类的话,可以在父类没有接口的情况下也能解决动态的问题,CGLibCglib实现动publicpublicclassimplementsMethodInterceptorprivateObject@param@param**@parampublicObjectintercept(Objectarg0,Methodarg1,Object[] arg3)throwsThrowable{returnnull;}privateObjectcreatePorxyInstatnce(Objectobject)//cglib使用该类创建目标对象的 Enhanceren=newEnhancer();//设 处理程//返回被创建 return}publicstaticvoidmain(String[]args){ =newCglib yInstatnce(newBusinessProcessImpl());}}差不多 InvocationHandlerinvokAPI中有这么一段:General-purposeEnhancercallbackwhichprovidesfor"around也就是说生成的这个方法连接会到EnhancercallbackEnhanceren=newEnhancer();//设 处理程GeneratesdynamicsubclassestoenablemethodGeneratesdynamicsubclassestoenablemethodinterception.ThisclassstartedasasubstitutethethestandardsupportincludedwithJDK1.3,butonethatallowedtheproxiesextendaconcretebaseclass,inadditiontoimplementinginterfaces.Thedynamicallysubclassesoverridethenon-finalmethodsofthesuperclassandhavehookswhichcallbacktouser-definedinterceptorimplementations.类,这样才可以生成子类类),setCallback//JDK//JDK.是publicObjectintercept(Objectarg0,Methodarg1,Object[]arg2, arg3)throwsThrowable{//TODOAuto-generatedmethodstub arg1.invoke(targetobject,return}CGLIB完成方法日志和权限验证功CGlib:支持没有接口 方式,原理publicclass implementsMethodInterceptor//用 类对privateObject//在创建CGlib的时候把 的对象传入进public (Object}//通过enhancer生 类,也就是 类的子publicObjectcreateCGlib Enhancerenhancer=newEnhancer();//设 类信息 类是父类, 类是子//设置回调对象,此对象returnenhancer.create();}//权限验证的方法,publicvoidSystem.out.println("----权限验证功 }//日志方法,publicvoidSystem.out.println("-----日志功 }publicpublicObjectintercept(Objectobject,Methodmethod,Object[]args, )throwsThrowable{ Objectobj=method.invoke(object,//如果满足条件,}else////obj=method.invoke(object,//}return}}CGLIB总结CGLIBfinal要求类不能是final的,要的方法要是非final、非static、非privateSpring的AOP就是基于和CGLIB两种方式来生成动态的.会根据是否有接口智SpringAOP面向切面编程(重要Spring在运行期创建,不需要特殊的编译器。spring有两种方式若目标对象实现了若干接口,spring就会使用JDK动态若目标对象没有实现任何接口,spring就使用CGLIB库生成目标对象的子AOP相关概念Aspect(切面指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面是横切性关注点的抽象joinpoint(连接点所谓连接点是指那些被到的点。在spring中,这些点指的是方法,因为Pointcut(切入点所谓切入点是指我们要对那些joinpoint进行的

温馨提示

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

评论

0/150

提交评论