您好,欢迎访问三七文档
面向切面编程(AOP)及其应用讲师:王鑫*在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。面向切面编程(AOP)就是对软件系统不同关注点的分离,开发者通过拦截方法调用并在方法调用前后添加辅助代码。面向切面编程(AOP)AOP它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即切面。所谓“切面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来。切面就是横切面,代表的是一个普遍存在的共有功能。☆AOP代表的是一个横向的关系AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Java代码publicclassBusinessLogic{publicvoidSomeOperation(){//日志记录;//权限验证;DoSomething();//事务控制;}}AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。AOP技术的实现业务逻辑组件在运行过程中,AOP容器会动态创建一个代理对象供使用者调用。该代理对象已经按程序员的意图将切面成功切入到目标方法的连接点上,从而使切面的功能与业务逻辑的功能同时得以执行。AOP技术是建立在Java语言的反射机制与动态代理机制之上的。classTest{publicvoidsayHello(){System.out.println(Hello,AOP);}}aspectMyAspect{publicpointcutsayMethodCall():execution(publicvoidTest.sayHello());before():sayMethodCall(){System.out.println(start...);}}publicclassTestClass{publicstaticvoidmain(String[]args){Testtest=newTest();test.sayHello();}}拦截是AOP(面向切面编程)的一种实现策略,在AOP中,某个方法或字段被访问,可以进行拦截,然后在其之前或者之后加入某些操作。AOP是一种编程概念,因此它并未绑定到任何特定的语言。事实上,它对所有单独的、垂直分解式(译注:AOP通常被认为是横向分解)的语言(不仅是OO语言)都有帮助。AOP在不同语言都有实现(如C++,Smalltalk,C#,C,Java).拦截器的设计原理Struts2.0的拦截器的设计体现了一种编程的设计理念。即面向切面编程AOP。拦截是AOP(面向切面编程)的一种实现策略,在AOP中,某个方法或字段被访问,可以进行拦截,然后在其之前或者之后加入某些操作。什么是拦截器拦截器(Interceptor)是动态拦截Action调用的对象。它提供了一种机制使开发者可以在一个Action执行之前或执行之后插入需要的代码。理解DRY规则在软件开发领域,有一个非常重要的规则:Don’tRepeatYourself,就是所谓的DRY规则,意思就是不要写重复的代码。我们可以看下面几个图,理解DRY规则:为什么要使用方法调用呢,而不是在三个地方使用重复的代码呢?很多初学者认为是为了编程简单,代码简洁。实际上,这是次要的。最重要的原因是为了软件后期的升级及维护。(相同的地方需要修改,有什么好处?)拦截器的意义可以这样理解,拦截器是对调用方法的改进。我们说某个实例是一个拦截器时,这是从行为上来说的,如果从代码的角度来看,拦截器也是一个类,类中包含有方法,只是这个方法比较特殊,它会在目标方法调用之前“自动”执行。看进一步改进图如下:☆作用:1.提供了更高层次的解耦2.允许改变被调用方法的方法体3.可以改变调用的目标方法实现原理我们好奇,系统如何自动的调用拦截器,而且知道到底调用哪个拦截器的方法?大部分时候,拦截器方法都是通过JDK的动态代理来调用,AOP的实现机制。拦截器在Struts2.0中的角色☆作用:1.拦截器是通过struts.xml文件配置的,从而实现了对Action通用操作的可插拔式管理。2.降低了Action与特定代码的耦合性3.提高了Action的复用性4.把多个Action中需要重复指定的代码取出,放在拦截器类中定义,从而提供更好的代码重用。Struts2中的拦截器在Struts2中已经在struts-default.xml中预定义了一些自带的拦截器,如timer、params等。如果在struts.xml中配置package标签中继承struts-default,则当前package就会自动拥有struts-default.xml中的所有配置。代码如下:packagename=xxxextends=struts-default.../package拦截器的定义在struts.xml文件中定义拦截器语法格式:interceptorname=”拦截器名”class=”拦截器实现类”/应用定义好的拦截器interceptor-refname=拦截器名/在struts-default.xml中有一个默认的引用,在默认情况下(也就是action中未引用拦截器时)会自动引用一些拦截器。这个默认的拦截器引用如下:default-interceptor-refname=defaultStack/上面在defaultStack中引用的拦截器都可以action中不经过引用就可以使用注意:!!!!!如果在action中引用了任何拦截器后,要使用在defaultStack中定义的拦截器,需要在action中重新引用。params拦截器使用当客户端的一个form向服务端提交请求时,如有textfield,代码如下:s:formaction=loginusernames:textfieldname=username/brpasswords:passwordname=password/brs:submit//s:form在提交后,Struts2将会自动调用login动作类中的setXX方法,并将文本框中的值通过setXX方法的参数传入。实际上,这个操作是由params拦截器完成的,params对应的类是com.opensymphony.xwork2.interceptor.ParametersInterceptor。由于params已经在defaultStack中定义,因此,在未引用拦截器的action中是会自动引用params的。如下面的配置代码,在访问login动作时,Struts2是会自动执行相应的setter方法的。actionname=loginclass=“com.ascent.action.LoginActionresult/success.jsp/resultresultname=input/login.jsp/result/action这样,登录表单中的用户名,密码参数就会在Action类中被set进去,完成登录功能。但如果在action中引用了其他的拦截器,就必须显示的引用params拦截器,Struts2才能调用相应的setter方法来初始化参数。如下面的配置代码所示:actionname=loginclass=“com.ascent.action.LoginActioninterceptor-refname=timer/interceptor-refname=logger/interceptor-refname=params/result/success.jsp/resultresultname=input/login.jsp/result/action我们可以不去配置params拦截器,配置timer和logger或任意一个,测试参数username、password的值,应该是没有得到表单提交的值,因为params拦截器已经不起作用了。使用拦截器栈为了能在多个动作中方便地引用同一个或几个拦截器,可以使用拦截器栈将这些拦截器个整体来引用。拦截器栈要在package标签中使用interceptors和子标签interceptor-stack来定可以象使用拦截器一样使用拦截器栈,packagename=demoextends=struts-defaultinterceptorsinterceptor-stackname=mystackinterceptor-refname=timer/interceptor-refname=logger/interceptor-refname=params//interceptor-stack/interceptorsactionname=loginclass=com.ascent.action.LoginActioninterceptor-refname=mystack//action/package
本文标题:61AOP
链接地址:https://www.777doc.com/doc-3603728 .html