IoC和AOP编程计算机毕业论文.doc_第1页
IoC和AOP编程计算机毕业论文.doc_第2页
IoC和AOP编程计算机毕业论文.doc_第3页
IoC和AOP编程计算机毕业论文.doc_第4页
IoC和AOP编程计算机毕业论文.doc_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

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

文档简介

本科毕业设计说明书(论文) 第 30 页 共 30 页IoC和AOP编程计算机毕业论文1 引言框架从某种意义上讲是某种应用的半成品,它是由一组组件所构成。对于程序的重用性与所设计的系统的扩展性以达到开发周期的缩减的目的与开发质量的提高等目的,往往是框架一直追求并良好的实现了的。在软件设计中,最终遵循的还是一个设计理念,就是“高内聚,低耦合”。框架一般是将问题分割成若干子问题进行一一攻破,从而起到易于控制、扩展,易于分配资源的效果。设计过程中,常常引入“层”的概念,及将各个义务分层实现。其间难免会出现耦合,而耦合度过高会降低系统的扩展性和维护性。而框架主要工作在层与层之间,很好的解决了这一问题。在软件设计中有一个概念叫做IoC,及控制反转,也叫DI(依赖注入),它主要就是实现层与层之间的松耦合。面向对象编程在软件设计中无处不在,非常完美的解决了代码重用。但有时候具体的业务贯穿整个系统,而往往这个业务是重复出现的,利用面向对象已不能很好解决。在这里便出现了AOP(面向切面编程),将其中相同的业务抽取出来进行统一解决。在这里不得不说一下Spring框架的强大魅力,Spring对IoC和AOP的操作可谓前无古人。本文主要利用IoC和AOP的概念,解决层与层之间的依赖关系以及重复业务的处理。1.1 研究背景上世纪末与本世纪初,J2EE开始盛行,主要归功于它对中间层概念提出了系统性标准。但事实上,它并没有取得实质性的成功,原因主要是因为不管从其效率、难度还是性能上来讲都不孚众望。在J2EE早期阶段,都是利用EJB技术来开发J2EE应用的。但是,对于EJB,其学习成本非常高也难于理解,而且要想应用EJB技术也是相当困难的。因为EJB强制程序员必须依照它的规范去继续各种不同的接口,这样便会导致代码冗余及相似。此外对于其配置既是纷繁复杂又是味同嚼蜡。对于使用JNDI查找对象也是如此。虽然xdoclet的应运而生和缓了其中部分的开发工作,但是EJB存在的各大问题都造成了对其使用的不方便性。随着Java语言的发展,AOP和IoC等技术的逐渐成熟,一种新的J2EE解决方案应运而生,即轻量级框架。11.2 研究平台本文主要是基于Eclipse平台,使用Java语言编写IoC和AOP的实现程序。1.2.1 Java语言Java是一种面向对象的,由Sun公司开发的程序设计语言,具体研发是James Gosling及其同事,在上世纪90年代末正式推出。Java的强大之处在于其跨平台性,可在不同操作系统上编写应用软件。Java语言不同于其他编程语言,其优势主要体现在它具有通用、高效、安全等优点。而且该语言的应用领域也极其广泛。在微型电脑、数据中心、超级计算机以及各种网页应用等都能见到Java的身影。虽然Java的编程风格与之C、C+非常接近,但与C语言不同的是,Java是完全的面相对象,对于C+核心的面向对象技术它也是完美的继承了。同时,Java一改C中指针的概念,取而代之的是引用的概念。同时也摒弃了C中运算符重载和多继承等特征。在此基础上,Java也增加了自己的新特性,就是垃圾回收机制,对于不再引用而又一直在内存中的引用进行回收处理。程序员也从中得益而不用手动进行内存管理。1.2.2 EclipseEclipse是一个开源的软件开发工具,同时也是功能完备,能进行商用的工业开发平台。主要组成为Eclipse项目、工具项目、技术项目,具体是指Eclipse Platform,JDT,CDT,PDE。其中,Eclipse Platform是可扩展的集成开发环境;JDT是Java开发工具,主要用于Java开发;CDT是C语言开发工具,主要用于C开发;PDE则是对插件的开发。Eclipse为构建IDE和建造块建立坚实的基础。对于Eclipse Platform,它允许第三方工具的无缝对接,从而起到无须辨别具体工具的功能体现在哪里的作用。2 IoC和AOP2.1 IoC(控制反转)IoC,英文全称为Inversion of Control,及控制反转,主要用于降低程序间的耦合度。控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。依赖注入应用比较广泛。22.1.1 依赖注入依赖注入就是容器全权负责组件,给予其回调接口和上下文条件。EJB和Apache Avalon 都使用这种方式。如此看来,对于依赖对象的查找以及资源的查找就必须使用容器提供的接口,控制反转也就体现在了回调接口上。容器提供应用代码资源也是通过回调接口的。 32.1.2 实现方式对于依赖注入,主要的实现方式分别为接口注入(Interface Injection)、Set方法注入(Setter Injection)和构造注入(Constructor Injection)。 接口注入在接口中定义要注入的信息再通过接口来完成此功能就叫接口注入。具体示例如下:编写一个IBiz接口,Dao层的注入将通过这个接口进行。假设该接口中有一getDao()方法,用于获取数据访问层的对象。public interface IBiz/* param dao 数据访问层对象*/public void getDao(Dao dao);对于想要进行数据库操作的类就必须得实现IBiz接口,业务逻辑类Biz实现这个接口IBiz。/* 具体实现IBiz接口的类,重写了getDao方法*/public class Biz implements IBusinessprivate Dao dao;Overridepublic void getDao(Dao dao)this.dao=dao;只有实现IBiz接口才能完成依赖注入。 Set方法注入Set方法注入就是在需要属性注入的类中定义一个Set方法,并设置注入元素为其参数。假设业务层Biz依赖数据访问层,且持有其属性,需定义一个Set方法来接受数据访问层的注入。public class Biz/数据访问层对象的引用private Dao dao;public void setDao(Dao dao)this.dao=dao;/其他调用数据访问层的方法及其他操作 构造注入构造注入就是在需要属性注入的类中提供一个有参构造,其参数就是注入的元素。假设业务层Biz依赖数据访问层,且持有其属性,可通过一个构造器来接受数据访问层的注入。public class Bizprivate Dao dao;public Biz(Dao dao)this.dao=dao;/其他调用数据访问层的方法及其他操作 IoC图解IoC容器待使用已配置好的系统组件POJOs配置信息产生图2.1 IoC图解2.2 AOP(面向切面编程) AOP就是Aspect Oriented Programming的缩写,意为:面向切面编程。具体是指它是一种通过预编译和动态代理来实现程序功能的统一维护的技术。5AOP是OOP的延续,是软件开发中的一个热点,是函数式编程的一种衍生范型。AOP技术可以使业务逻辑的各个功能模块耦合度降低,从而达到提高程序的重用性和开发效率。 62.2.1 实现技术对于AOP技术的实现,主要可通过以下两种方式实现:一种是动态代理,对原有对象的行为通过截取消息,修饰消息,最终执行修饰后的行为;另一种是静态织入,以特定语法创建切面,以达到编译器在编译期织入切面代码的目的。7然而殊途同归,实现AOP的技术特性却是相同的,分别为:(1) join point(连接点):连接点是程序运行过程中具体的执行点,比如它 可以是一个方法。对于连接点并不是一个具体的概念,所以在是实现AOP时并不用去定义它。(2) point cut(切入点):对于切入点这个概念,它实质上是一个捕获连接点的一种结构。所以在实现AOP中,可通过定义一个切入点来拦截相关方法的调用。(3) advice(通知):本质上是切入点是执行程序,具体执行切面的逻辑。(4) aspect(方面):切点与通知合称切面,虽与面向对象中的类相似,但它更多的表达的是对象间的横向关系。(5) introduce(引入):以附加属性方法的形式达到修改对象结构的目的。有的AOP工具又将其称为mixin。2.2.2 主要目的对于AOP的主要目的大致可分为事务处理、性能监测、日志记录、安全控制等。82.2.3 主要意图对逻辑代码中事务处理、性能监测、日志记录、安全控制等的处理从中分离,重新独立到非向导业务方法中。此等做法的好处是在修改这些代码的时候不影响业务逻辑,进一步体现了软件开发的“开闭原则”。92.3 注解(Annotation)Annotation(注解)是JDK5.0及以后版本引入的。对于注解,主要作用大致是监测代码依赖性,创建文档,通过注解甚至可以执行基础的编译检查。10注解的编写方式是以“”开头加上自定义的注解名,通过其参数个数的不同,大致可分为三类:单值注解、标记注解和完整注解。注解只是作为标识存在,一般不会直接影响到程序的语义,通过反射机制我们可以访问到这些元数据,元数据就是用来描述数据的数据。注解的存在级别一共有三种:RUNTIME,CLASS,SOURCE。RUNTIME表示运行时存在,CLASS表示能作用于class文件,SOURCE表示只存在源代码中。程序员可在编译时选择代码的存在级别。 112.3.1 基本作用虽然对于注解的作用还没有明确的定义,但是大致可以分为三种:(1) 编写文档:检查代码中存在的标识注解来生成文档。(2) 代码分析:以代码中标识的注解对代码进行分析。(3) 编译检查:检查标识的注解使编译器能执行基础的编译检查。122.3.2 基本的内置注解(1) Override:只能用在方法上,用来申明该方法是改写父类的。(2) Deprecated:对于弃用的方法添加的注解。当程序员调用这些方法时, 在编译时将会显示提示信息。该注解可添加在程序的所有元素上。 (3) SuperressWarnings:暂时关闭警告信息。133 基于注解的IoC和AOP的实现就IoC而言,主要实现是靠设计模式中的工厂模式,工厂模式负责将大量具有Component注解的类进行实例化,而不必事先知道每次是要实例化哪一个类。换句话说,工厂模式对于具体的new的细节都进行了隐藏和封装。对于工厂模式的优点主要分为下列四点:(1) 代码结构清晰,具有良好的封装性。对于对象的创建不是无条件的。假设一个调用者需要一个具体的产品,调用者并不需要知道产品具体是如何被生产的。对于他而言只需要知道产品类名或者产品约束字符串就可以了,从而降低模块耦合度。(2) 优秀的可扩展性。如果具体需求需要增加产品,不必具体对产品类进行修改,只需适当修改工厂类或者再增加一个工厂就可以了。(3) 屏蔽产品类。对于具体产品是如何生产的,调用者并不用关心,他的关注点主要在于产品的接口。如果产品接口不发生变化,那么系统上层的模块也不会发生改变。具体的产品的实例化主要由工厂类管理,对于不同的产品对象的生产应取决于不同的工厂类。(4) 关于工厂方法的经典应用就是解耦合了。处于较高层的模块只需知道实现类的接口,具体实现类无需关心。对于工厂方法,它也遵循迪米特和依赖倒置法则,仅仅依赖实现类的接口;除此之外,工厂方法也遵循里氏替换原则,子类可以随时随地替换父类。14而对于AOP来说,在扫描系统组件时,如果该组件存在Interception注解且已声明需要拦截的方法。那么在调用存在Interception注解的类的方法时,如果该方法已被拦截,则该方法执行前和执行后会进行相应的操作。而实现AOP技术主要用到了代理模式。对于使用代理模式,只要有点体现在以下几个方面:(1) 职责清晰:具体的产品类实现具体的业务,不必去在意非自身所要实现的业务。如需其他业务可通过后期代理完成附加,此种做法的好处是代码简洁清晰。(2) 高扩展性:对于产品类可能需求不同,但是只要是实现了其接口的,可通过代理手段代理各种产品类,而代理类却不用做任何修改。(3) 智能化:代理对象可在运行时才去调用具体的代理类,换言之就是代理类可以在运行时才确定代理对象。153.1 注解的编写在本文中,主要用到的注解有Component,Property,Aspect,Interception。Component注解主要说明该类是一个组件,用于在初始化容器时将其实例创建放入一个Map中;Property注解主要说明该类是组件类的属性,在运行时将注入属性,以便调用该类的方法;Aspect注解主要用于说明该类是一个切面类,用来执行在拦截方法执行过程中要处理的操作;Interception注解用于说明该类中的方法需要被拦截,可指定要拦截的方法,拦截下来的方法将先进行其他操作,如事务处理。具体注解的代码如下:Component注解:public interface Component /组件在HashTable中的名字,当为空时默认为组件类名的小写public String name() default ;/组件是否存在单例,默认为存在public boolean isSingleton() default true;Property注解:public interface Property /需要注入的属性注入的对象的名称,默认为空时则直接获取组件中属性的名称public String ref() default ;Aspect注解:public interface Aspect /切面类的名称public String name() default ;Interception注解:public interface Interception /拦截的方法public Stringmethods();3.2 IoC实现(对象工厂)首先,在工厂初始化的时候会创建组件的对象,而对于组件类的存放放在对应的包中,对于读取的包及包的扫描则配置在XML中。读取XML获取包名及子包名代码如下:String packageInfo=;URL url=XMLParse.class.getResource();File file=new File(url.getPath()+xmlName);DocumentBuilder builder=null;try builder=DocumentBuilderFactory.newInstance().newDocumentBuilder();Document doc=builder.parse(file);Element ele=doc.getDocumentElement();NodeList nls=ele.getChildNodes();Element ce=null;for (int i = 0; i nls.getLength(); i+) Node n=nls.item(i);if(n.getNodeType()=Node.ELEMENT_NODE)if(n.getNodeName().equals(component-package)ce=(Element)n;break;packageInfo=ce.getTextContent(); catch (Exception e) e.printStackTrace();其次通过包名,获取包中的所有类,而类的存放是以文件形式存在,则需进行文件的扫描。文件扫描代码如下:public void findAndAddClassesInPackageByFile(String packageName,String physicsPath, final boolean recursive, SetClass classes) /获取此包的目录建立一个fileFile dir=new File(physicsPath);/如果不存在或者也不是一个目录就直接返回if(!dir.exists()|!dir.isDirectory()return;/如果存在就获取包下的所有文件及目录File dirFiles=dir.listFiles(new FileFilter() Overridepublic boolean accept(File file) /如果可以循环(即包含子目录)或是以.class结尾的文件(即编译好的java文件)return (recursive&file.isDirectory()|(file.getName().endsWith(.class););/循环所有文件for (File file : dirFiles) /如果是目录则继续扫描if(file.isDirectory()findAndAddClassesInPackageByFile(packageName+.+file.getName(), file.getAbsolutePath(), recursive, classes);else/如果是java类文件去掉后面的.class只留下类名String className=file.getName().substring(0,file.getName().length()-6);/System.out.println(className);try /添加到集合中/System.out.println(packageName+.+className);classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName+.+className); catch (Exception e) e.printStackTrace();获取包中所有类的代码如下:public SetClassgetClasses(String packages)/存放包中的classSetClassclasses=new LinkedHashSetClass();/是否迭代循环boolean recursive=true;/将包名从以.隔开换成以/隔开String packageName=packages;String packageToDir=packageName.replace(., /);/System.out.println(packageToDir);/定义一个枚举的集合循环处理该目录下的所有东西Enumeration dirs;try dirs=Thread.currentThread().getContextClassLoader().getResources(packageToDir);/循环迭代while(dirs.hasMoreElements()/获取下一个元素URL url=dirs.nextElement();/获取协议名String protocal=url.getProtocol();/如果是文件形式保存在服务器上if(file.equals(protocal)/System.err.println(file类型的扫描);/获取包的物理路劲String physicsPath=URLDecoder.decode(url.getFile(), utf-8);/sSystem.out.println(physicsPath);/以文件方式扫描整个包下的文件并添加到集合中findAndAddClassesInPackageByFile(packageName,physicsPath,recursive,classes);else if(jar.equals(protocal)/如果是jar文件,则定义一个jarFileJarFile jar;try /获取jarjar=(JarURLConnection)url.openConnection().getJarFile();/从此jar包中获取一个枚举类Enumerationentries=jar.entries();/同样进行循环迭代while(entries.hasMoreElements()/获取jar里的一个实体,可以是目录和一些jar包里的其他文件,如META-INF等文件JarEntry entry=entries.nextElement();String name=entry.getName();/如果以/开头if(name.charAt(0)=/)/获取/后的字符串name=name.substring(1);/如果前半部分与定义的包名相同if(name.startsWith(packageToDir)/若以/结尾是一个包int index=name.lastIndexOf(/);if(index!=-1)/获取包名且把/替换成.packageName=name.substring(0,index).replace(/, .);/若可迭代下去且是一个包if(index!=-1)|recursive)if(name.endsWith(.class)&!entry.isDirectory()/去掉.class获取正真的类名String className=name.substring(packageName.length()+1,name.length()-6);try /添加到classes中classes.add(Class.forName(packageName+.+className); catch (Exception e) e.printStackTrace(); catch (Exception e) e.printStackTrace(); catch (Exception e) e.printStackTrace();return classes;接着就是对工厂的初始化。具体代码如下:public void init() /获取配置文件中的包信息String packageInfo=XMLParse.getInstance().getPackage();/System.out.println(packageInfo);/获取包下的所有classSetClassclasses=getClasses(packageInfo);/System.out.println(classes.size();for (Class cls : classes) /判断是否存在Component注解if(cls.isAnnotationPresent(Component.class)/获取注解对象Component component=cls.getAnnotation(Component.class);/获取注解name的属性值String comName=();try /判断注解comName是否为空if(comName.equals()/如果为空将comName设置为类名的小写comName=cls.getSimpleName();comName=comName.substring(0,1).toLowerCase()+comName.substring(1);/System.out.println(comName);/最终将处理后或未处理的类名对应的实例存入cms中cms.put(comName, cls.newInstance(); catch (Exception e) e.printStackTrace();接下来则是在程序运行过程中,对存在Property注解的属性进行属性注入,获取其对应的实例对象。具体代码如下:public T getObject(String name,Class cz)T target=(T)cms.get(name);/获取组件时首先要判断该组件是否存在if(target=null)throw new RuntimeException(对象不存在);/如果对象存在,则要判断对象是否需要注入属性,如果需要注入属性,则先注入属性在返回对象Field fields=target.getClass().getDeclaredFields();for (Field field : fields) /判断该属性是否存在Property注解if(field.isAnnotationPresent(Property.class)/获取属性名String fieldName=field.getName();Property pro=(Property)field.getAnnotation(Property.class);String ref=pro.ref();/判断ref是否为空if(ref.equals()ref=fieldName;/获取set方法的名称String methodName=set+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);try Method m=cz.getMethod(methodName, field.getType();m.invoke(target, this.getObject(ref, field.getType(); catch (Exception e) e.printStackTrace();/target=this.getObject(fieldName, cz);if(target.getClass().isAnnotationPresent(Interception.class)Interception inter=target.getClass().getAnnotation(Interception.class);/拦截的方法String methods=inter.methods();SpringInterceptor mi=null;try mi=(SpringInterceptor)Class.forName(interceptionName).newInstance();mi.setMethodsName(methods);mi.setTarget(target.getClass().newInstance(); catch(ClassNotFoundException e)e.printStackTrace();catch (InstantiationException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (IllegalAccessException e) / TODO Auto-generated catch blocke.printStackTrace();return (T)mi.getInstance();return target;在属性注入的同时会判断该属性是否存在拦截器以及要拦截的方法。接下来则是利用AOP实现拦截器功能。3.3 AOP实现(拦截器)对于拦截器,其实就是代理模式的具体实现,首先需实现InvocationHandler接口,该接口是代理实例的调用处理程序实现的接口。对于各个代理实例都被联接了具体的处理程序代码。在代理实例调用处理程序时,将对该程序方法编码设置且将其指派到它的invoke方法。 以下是实现InvocationHandler的抽象类,该类需要一个目标对象及该目标对象需要拦截的方法。具体代码如下:public abstract class SpringInterceptor implements InvocationHandler /目标对象private Object target;/所要拦截的方法private String methodsName;public Object getInstance()Object obj=Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);return obj;public void setTarget(Object target)this.target=target;public void setMethodsName(String methodsName)this.methodsName=methodsName;Overridepublic Object invoke(Object proxy, Method method, Object args)throws Throwable for (String name : methodsName) if(name.equals(method.getName()return interceptor(target,method,args);return method.invoke(target, args);/* * * param target 拦截类的对象 * param method 拦截的方法 * param args 方法的参数 * return 返回值 * throws IllegalArgumentException * throws IllegalAccessException * throws InvocationTargetException */public abstract Object interceptor(Object target, Method method, Object args)throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;接下来则是编写具体实现拦截功能的实现类。具体代码如下:public class MyInterception extends SpringInterceptor Overridepublic Object interceptor(Object target, Method method, Object args)throws IllegalArgumentException, IllegalAccessException,InvocationTargetException Object result=null;System.out.println(开启事务);result=method.invoke(target, args);System.out.println(提交事务);return result;至此,基本实现了拦截器功能。对于AOP编程,能实现的功能主要有事务处理、性能监测、日志记录、安全控制等,在这里只是象征性的输出语句。3.4 IoC和AOP实现流程图根据IoC和AOP的描述以及实现程序,绘制了实现的基本流程图,如图3.1和图3.2所示:读取XML文件获取组件的包名扫描包,获取包及子包中所有的类Component注解是否存在注解name是否为空类名以头分格式以键值形式将对象存入Map中Y按指定名字以键值对形式将对象存入Map中YN图3.1 初始化对象工厂流程图是否存在Aspect注解获取该类名结束Y开始开始对象是否存在对象类是否存在Property以name获取Map中的对象调用set方法注入对象是否存在Interception获取拦截方法调用Aspect类执行拦截操作结束YNYYY图3.2 获取对象及AOP实现流程图4 基于注解的IoC和AOP的框架在WEB中的应用下面是该框架在WEB中的应用,主要为了验证IoC和AOP,所以只是实现了简单的增删改查,而没有过多是去追求系统的其他功能。前台显示页面利用AJAX异步请求数据,当访问主页就会显示数据,对于显示的方法并没有进行拦截。提供基本的增删改功能,当点击相应功能时会提交给servlet进行处理,servlet中将创建service层的对象,而对象的创建利用框架中的获取对象方法,而不是直接new出来,实现了层与层之间的松耦合。在service层将申明dao层的属性,配有setDao方法获取属性对象。而在dao层中将实现方法的拦截,拦截的方法主要就是增删改,对于拦截的方法会进行相应的处理,而在这只是象征性的输出语句。下面是WEB的具体实现。表4.1 用户信息表序号列名类型含义备注1idintid主键2usernameVarchar用户名345usernouserageusergenderVarcharintVarchar用户编号用户年龄用户性别4.1 用户显示当客户端访问主界面时,主界面中利用AJAX异步请求servlet,将传过去一个op,也就是请求的操作。servlet根据请求的op判断该执行什么操作,然后调用相应的方法。在这里则是进行查询操作。在servlet中将使用框架中的对象工厂获取service层,也就是业务层的对象,所以servlet将调用service层的查询方法。而在service层中存在dao层(数据访问层)的属性,要想获取dao层的对象,首先需对dao属性进行set处理,这样在对象工厂初始化的时候凡是有Property注解的将通过set方式注入其对象。当然也会判断该属性对应的类是否需要方法拦截。在该web显示中只对修改、删除和更新用户的方法进行了拦截,对于其他方法并没有进行拦截。用户显示如下图所示:图4.2 用户信息显示查询用户的servlet代码如下所示:/查询相关用户Listusers=userService.queryUser();ObjectMapper mapper=new ObjectMapper();/将其转换成json数据String json=mapper.writeValueAsString(users);response.setCharacterEncoding(utf-8);PrintWriter pw=response.getWriter();pw.write(json);pw.flush();pw.close();4.2 用户的增删改对于用户的增删改操作,具体实现方法不同,但大致的操作过程和查询用户类似,在这里就不再赘述。唯一有区别的就是,对于用户的增删改方法进行了方法拦截,即在dao层中存在Intecerption注解,并指明了拦截的方法有“saveUser”,“delUser”和“updateUser”。对于拦截的方法采用AOP编程思想,将调用具有Aspect注解的类,在方法执行过程中执行该类相应的方法。但是在本web实现中也只是象征性的输出语句。具体增加修改用户的页面和进行拦截的结果如下所示:图4.3 增加用户图4.4 修改用户增删改底层公共代码如下:/* 底层增删改公共类* param sql 执行的sql语句* param o sql语句占位参数*/public void execute(String sql,Object o)Connection con=null;PreparedStatement ps=null;try con=getCon();ps=con.prepareStatement(sql);for (int i = 0; i o.length; i+) ps.setObject(i+1, oi);ps.executeUpdate(); catch (Exception e) e.printStackTrace();finallycloseAll(null, ps, con);对拦截的方法同样也会进行AOP处理。具体效果如下图:图4.5 拦截方法执行结果5 系统测试5.1 测试方案设计在本框架设计过程中通常会遇到这样那样的问题。所以以下测试主要是为了发现并解决在设计过程中遇到的问题。其中主要测试的模块是XML解析获取包名,根据包名获取包及子包中的所有类,获取类中属性的对象以及AOP测试。对于测试,主要运用Junit4测试。对于Junit测试,它是Java语言的单元测试框架,主要用于白盒测试。以下是具体的测试模块:(1) 解析XML获取包名测试。运用测试用例对获取包名的过程进行测试。(2) 根据包名获取包及子包中所有类的测试。根据提供的包名,运用程序中的获取方法,建立单元测试进行包中类的获取。(3) 获取类中属性对象的测试。对类中持有其他类引用且具有Property注解的属性注入对象的测试,测试是否对象一注入。(4) AOP测试。对拥有Interception注解的类中申明的方法进行拦截测试,测试是否对该方法进行了拦截。5.2 测试结果及分析(1) 解析XML获取包名测试编写XML文件,其中设置被扫描包的信息。运行单元测试,发现能进行正常的XML解析获取包名,达到预期的效

温馨提示

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

评论

0/150

提交评论