Spring的AOP模块.docx

上传人:b****2 文档编号:16970630 上传时间:2023-07-20 格式:DOCX 页数:12 大小:34.11KB
下载 相关 举报
Spring的AOP模块.docx_第1页
第1页 / 共12页
Spring的AOP模块.docx_第2页
第2页 / 共12页
Spring的AOP模块.docx_第3页
第3页 / 共12页
Spring的AOP模块.docx_第4页
第4页 / 共12页
Spring的AOP模块.docx_第5页
第5页 / 共12页
Spring的AOP模块.docx_第6页
第6页 / 共12页
Spring的AOP模块.docx_第7页
第7页 / 共12页
Spring的AOP模块.docx_第8页
第8页 / 共12页
Spring的AOP模块.docx_第9页
第9页 / 共12页
Spring的AOP模块.docx_第10页
第10页 / 共12页
Spring的AOP模块.docx_第11页
第11页 / 共12页
Spring的AOP模块.docx_第12页
第12页 / 共12页
亲,该文档总共12页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Spring的AOP模块.docx

《Spring的AOP模块.docx》由会员分享,可在线阅读,更多相关《Spring的AOP模块.docx(12页珍藏版)》请在冰点文库上搜索。

Spring的AOP模块.docx

Spring的AOP模块

第3章Spring的AOP模块

本章学习目的和要求

本章重点和难点

AOP是Spring框架的另一个重要特征。

AOP(AspectOrientedProgramming,面向切面编程)把一个业务流程分成几部分,例如权限检查、业务处理、日志记录,每个部分单独处理,然后把它们组装成完整的业务流程。

每个部分被称为切面(Aspect)或者关注点。

3.1实例:

使用拦截器拦截方法(在struts-2.3.8中复制commons-logging-1.1.1、aopalliance-1.0.jar)

AOP有一些重要的概念,包括切面(Aspect)、连接点(Joinpoint)、通知(Advice)、切入点(Pointcut)、引用(Introduction)等。

这些概念并不是Spring定义的。

对于刚刚接触AOP的开发者来说,这些概念非常抽象,往往很难理解。

抛开这些抽象的概念,先来看一个AOP例子。

前面的章节中曾介绍了一个AOP的例子。

下面看一下稍微复杂的例子。

本例中,AOP的规则要稍微复杂一些。

3.1.1Service接口

Spring推荐使用接口编程。

该接口定义了两个方法。

一会儿将使用拦截器拦截其中的withAop()方法,而另一个方法withoutAop()将不会被拦截。

IAopService.java

packagecom.helloweenvsfei.spring.aop;

publicinterfaceIAopService

{//Service接口,定义两个方法

publicvoidwithAop()throwsException;//将会被拦截

publicvoidwithoutAop()throwsException;//不会被拦截

}

3.1.2Service实现代码

IAopService实现类中定义了一个name属性,以及对应的getter、setter方法。

实现类代码为:

AopServiceImpl.java

packagecom.helloweenvsfei.spring.aop;

importjavax.security.auth.login.AccountException;

publicclassAopServiceImplimplementsIAopService

{

//Service实现

privateStringname;//name属性

publicvoidwithAop()throwsException

{

//withAop方法实现

System.out.println("有AOP的函数运行。

name:

"+name);

if(name.trim().length()==0)//如果name为空

thrownewAccountException("name属性不能为空");//则抛出异常

}

publicvoidwithoutAop()throwsException

{

//withoutAop方法实现

System.out.println("没有AOP的函数运行。

");

}

publicStringgetName()

{

//getter方法

returnname;

}

publicvoidsetName(Stringname)

{

//setter方法

this.name=name;

}

}

3.1.3方法前拦截器检查name是否为null

下面是方法前拦截器,实现自MethodBeforeAdvice接口。

方法前拦截器在执行指定方法前被调用,参数分别为被调用的方法、执行时被传入的参数、被拦截的Bean。

代码为:

MethodBeforeInterceptor.java

packagecom.helloweenvsfei.spring.aop;

importjava.lang.reflect.Method;

importorg.springframework.aop.MethodBeforeAdvice;

publicclassMethodBeforeInterceptorimplementsMethodBeforeAdvice

{

//方法前拦截器

//调用对象的方法前将执行该方法。

参数分别为被调用的方法、被调用调用方法的参数、对象

publicvoidbefore(Methodmethod,Object[]args,Objectinstance)throwsThrowable

{

System.out.println("即将要执行方法:

"+method.getName());//打印控制台

if(instanceinstanceofAopServiceImpl)

{

//如果是Service

Stringname=((AopServiceImpl)instance).getName();//获取name

if(name==null)//检查是否为空

thrownewNullPointerException("name属性不能为null");

}

}

}

3.1.4返回后拦截器输出返回值

返回后拦截器,实现自AfterReturningAdvice接口。

返回后拦截器在执行完指定方法、并返回之后被调用。

如果有返回值,可以取到返回值,否则为null。

参数分别为方法返回值、被调用的方法、执行时被传入的参数、被拦截的Bean。

代码为:

MethodAfterInterceptor.java

packagecom.helloweenvsfei.spring.aop;

importjava.lang.reflect.Method;

importorg.springframework.aop.AfterReturningAdvice;

publicclassMethodAfterInterceptorimplementsAfterReturningAdvice

{

//方法后拦截器

publicvoidafterReturning(Objectvalue,Methodmethod,Object[]args,Objectinstance)throwsThrowable

{

System.out.println("方法"+method.getName()+"运行完毕,返回值为:

"+value);

}

}

3.1.5异常拦截器捕获异常

异常抛出拦截器,实现自ThrowsAdvice接口。

如果指定的方法中有异常被抛出,被调用。

与上两个拦截器接口不同,ThrowsAdvice接口没有定义任何方法,因此不需要实现任何方法。

但是如果定义了形如

afterThrowing([Method],[args],[target],subclassOfThrowable)

的方法,这些方法将会被调用。

参数分别为:

被调用的方法、方法的参数、被拦截的Bean以及抛出的异常类。

这里面只有最后一个参数是必须的。

Spring之所以这样设计,是为了是开发者灵活的定义多个方法捕捉不同的异常。

代码为:

packagecom.helloweenvsfei.spring.aop;

importjava.lang.reflect.Method;

importjavax.security.auth.login.AccountException;

importorg.springframework.aop.ThrowsAdvice;

publicclassThrowsInterceptorimplementsThrowsAdvice

{

//异常拦截器

publicvoidafterThrowing(Methodmethod,Object[]args,Objectinstance,AccountExceptionex)throwsThrowable

{

System.out.println("方法"+method.getName()+"抛出了异常:

"+ex);

}

publicvoidafterThrowing(NullPointerExceptionex)throwsThrowable

{

System.out.println("抛出了异常:

"+ex);

}

}

3.1.6拦截器配置

然后把三个拦截器连同Service实现类配置到Spring中。

Spring将实例化三个拦截器对象、一个Service对象,并安装指定的规则装配。

配置代码为:

ApplicationContext.xml

xmlversion="1.0"encoding="UTF-8"?

>

//www.springframework.org/schema/beans"

xmlns:

xsi="http:

//www.w3.org/2001/XMLSchema-instance"

xsi:

schemaLocation="http:

//www.springframework.org/schema/beanshttp:

//www.springframework.org/schema/beans/spring-beans-2.0.xsd">

--拦截器在withAop()方法前运行-->

--拦截器在withAop()返回后运行-->

class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

--拦截器在异常抛出后运行-->

class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

class="org.springframework.aop.framework.ProxyFactoryBean">

--拦截器-->

aopMethodBeforeInterceptor

aopMethodAfterInterceptor

aopThrowsInterceptor

--被拦截的对象-->

3.1.7运行代码

运行代码从Spring容器中获取Service对象,并分别执行Service的两个方法withAop()与withoutAop()。

Spring将会在withAop()方法前后添加拦截器,但withoutAop()方法前后不会。

代码为:

AopRun.java

packagecom.helloweenvsfei.spring.aop;

importorg.springframework.beans.factory.xml.XmlBeanFactory;

importorg.springframework.core.io.ClassPathResource;

publicclassAopRun

{

publicstaticvoidmain(String[]args)throwsException{

XmlBeanFactoryfactory=newXmlBeanFactory(//获取Factory

newClassPathResource("applicationContext.xml"));

IAopServicehello=(IAopService)factory.getBean("aopService");//查找对象

hello.withAop();//执行withAop()

hello.withoutAop();//执行withoutAop()

factory.destroySingletons();//销毁对象

}

}

运行效果如图3.1。

图3.1拦截器运行效果

在本例中,由于没有异常抛出,因此ThrowsInterceptor没有起作用。

读者可以在xml中设置name属性为null或者空字符串,使withAop()方法中抛出异常,观察运行效果。

3.2拦截器与Filter的区别

Spring的拦截器与Servlet的Filter有相似之处,比如二者都是AOP编程思想的体现,都能实现权限检查、日志记录等。

不同的是:

3.2.1使用范围不同

Filter是Servlet规范规定的,只能用于Web程序中。

而拦截器即可以用于Web程序,也可以用于Application、Swing程序中。

3.2.2规范不同

Filter是在Servlet规范中定义的,是Servlet容器支持的。

而拦截器是在Spring容器内的,是Spring框架支持的。

3.2.3使用的资源不同

同其它的代码块一样,拦截器也是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里的任何资源、对象,例如Service对象、数据源、事务管理等,通过IoC注入到拦截器即可;而Filter则不能。

3.2.4深度不同

Filter在只在Servlet前后起作用。

而拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用具有更大的弹性。

因此在Spring构架的程序中,要优先使用拦截器。

3.3AOP的相关概念

看一下面向切面的编程的几个常用的概念:

切面Aspect、通知Advisor与切入点Pointcut。

3.3.1切面Aspect

在本例中,方法withAop()、withoutAop()中都有一些代码。

虽然只是一些输出语句,但是在真实的程序中这里应该是一些有意义的代码(如读写数据库、权限检查、异常情况记录等)。

这些代码可以看作是AOP中的切面(Aspect)。

可以将切面理解为模块。

3.2.2通知Advisor

本例的三个拦截器都是实现自某个Advisor接口。

从类名上看就知道三个拦截器都是AOP中的通知(Advisor)。

一旦Spring符合条件,就会派发出通知。

与生活中的通知不同的地方在于,Spring中的通知是带有执行代码的,实现某种功能。

3.3.3切入点Pointcut

在配置拦截器的时候,xml中只配置了withAop()方法使用拦截器,而withoutAop()方法没有配置拦截器。

这种配置是借助于org.springframework.aop.support.NameMatchMethodPointcutAdvisor完成的。

从类名称上看,这是一个切入点(Pointcut)。

该类对象能配置对哪些方法使用拦截器,从哪个地方“切入”进去。

配置时可以使用通配符。

该类名上也带有Advisor是因为它是用通知(Advisor)实现的。

简单地说,“切入点”负责往“什么地方”插入代码,而“通知”负责插入“什么代码”。

3.3.4切入点配置方式

Spring提供灵活的切入点配置方式。

例如使用正则表达式。

下面是Spring官方的一个使用正则表达式的例子。

Spring接受Perl5支持的正则表达式:

class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

--切入点-->

--拦截器-->

--正则表达式配置切入点-->

.*get.*

--包含get的方法-->

.*absquatulate

--包含absquatulate的方法-->

3.4AOP的代理模式

代理模式是Spring中常用的设计模式。

Spring提供了几个常用的代理类,例如普通的代理类、事务代理类等等。

3.4.1ProxyFactoryBean代理工厂对象

上例配置AopServiceImpl时使用了org.springframework.aop.framework.ProxyFactoryBean类。

这是Spring内置的代理类,引入了一个中间层,能够创建不同类型的对象。

利用它可以实现任何形式的AOP。

3.4.2TransactionProxyFactoryBean事务代理工厂对象

另一个很有用的代理类是TransactionProxyFactoryBean,是ProxyFactoryBean的子类,常用在数据库编程上。

Spring利用TransactionProxyFactoryBean对事务进行管理,在指定方法前利用AOP连接数据库并开启事务,然后在指定方法返回后利用AOP提交事务并断开数据库。

例如Spring宠物商店里的事务性配置:

class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl">

--其余的配置略-->

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

PROPAGATION_REQUIREDpropagetion

PROPAGATION_REQUIRED

PROPAGATION_REQUIRED,readOnly

事务管理配置详见本章后面的DAO模块与ORM模块。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 英语

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2