spring aop实例(转载)

Spring  AOP只实现了针对方法调用的拦截及增强,在j2ee应用中,拦截到方法级的操作已经足够。spring  AOP让Spring支持声明式事务。为了使用spring AOP,首先要了解它的API结构

AOP联盟API
一套用于规范AOP实现的底层API,String的AOP框架也是直接以这些API为基础构建的。
Aop包:定义了增强(Advice)接口和AOP运行时异常AspectException
Intercept包:拦截器包,规范了连接点(join point)及增强(advice)的类型
Instrument和reflect包:切面与应用模块如何集成在一起

切入点(point cut):即要在哪里切入代码。
Spring使用Pointcut接口表示切入点,并预定义了几个切入点实现类:
(1)NameMathMethodPointcut:方法名称匹配切入点,它的mappedname和 mappedNames属性表示匹配的方法名,名称只支持“*”通配符,代表0个或多个字符
(2)JdkPegexpMethodPointcut:正则表达式切入点,如果是JDK1.4以下版本,使用Perl5RegexpMethodPointcut,这时要导入jakarta-oro-xx.jar包。它的patternt和patterns表示匹配方法名称的正则表达式,excludePattern和excludePatterns表示要排除的方法名称正则表达式。
(3)expression_r_r_rPointcut:描述式切入点接口,用表达语言来描述切入点,spring提供了一个实现类,即AspectJexpression_r_r_rPointcut,它的expression_r_r_r属性表示要描述的切入点。使用这个类要用于AspectJ中的语法解析处理器,这时要引入aspectjweaver.jar包。

增强(advice):也就是要切入什么代码。
Spirng Aop增强类型是围绕方法调用连接点展开的,提供了以下四种类型;
(1)MethodBeforAdvice:方法调用前增强接口。用户要实现它的before()方法
(2)AfterReturningAdvice:返回后增强接口。用户要实现它的afterReturning()方法。
(3)ThrowsAdvice:异常增强接口。这是个标识接口,但在实际应用中,用户要学现afterThrowing()方法。
(4)MethodInterceptor:环绕增强接口。又称拦截器,是个标识接口,在实际应用中,用户要学现它的invoke()方法。

引介(Introduction):在不更改源代码的情况下,给一个类增加属性、方法以及让它实现其它接口或其它父类。spring使用引介拦截器IntroductionInterceptor定义引介,它的implementsInterface属性用来指定要实现的某个接口,spring提供该接口的两个实现:
(1)DelegatingIntroductionInterceptor:实例化时要引入接口实现作为参数
(2)DelegatePerTargetObjectDelegatingIntroductionInterceptor:实现化时要引入一个接口及实现类作为参数。

增强器(Advisor):一个切面的模块化封装(如把切入点和增强封装为一个整体,它们是无法单独使用的),简称切面。有以下两大类:
(1)由切入点(point cut)及增强(advice)组合的切面。
(2)组合引介的切面
Spring Aop最底层的切面封装是Advisor接口,其下面还有两个接口IntroductionAdvisor(引介增强器)及PointcutAdvisor(切入点增强器),它们有几下几种实现:
(1)DefaultPointcutAdvisor:默认的切面封装。它的advice及pointcut属性分别指增强和切入点。
(2)NameMatchMethodPointcutAdvisor:方法匹配切入点切面。不用专门定义切入点,只要指定增强。它的mappedName属性指定切入点匹配的方法名称,advice属性指定增强。
(3)RegexpMethodPointcutAdvisor:正则表达式切入点切面。不用专门定义切入,只要指定增强。它的advice属性表示要包装的增强,pattern和patterns属性表示要设置的切入点
(4)AspectJexpression_r_r_rPointcutAdvisor:AspectJ表达式切入点切面。不要专门定义切入点,只要指定增强。它的advice属性表示要包装的增强,expression_r_r_r表示要生成切入点的表达式。
(5)DefultIntroductionAdvisor:引介增强器(IntroductionInterceptor)的实现

代理工厂(ProxyFactory):spring AOP是基于代理实现的,代理工厂用来创建代理对象。Spring的AOP提供了以下几个代理工厂实现。
(1) ProxyFactoryBean:一般代理工厂
(2) TransactionProxyFactoryBean:事务代理工厂
(3) LocalStatelessSessionProxyFactoyBean:用于创建EJB代理的代理工厂
(4) BeanNameAutoProxyCreator:根据名称自动创建代理
(5) DefaultAdvisorAutoProxyCreator:根据切面自动创建代理

AOP笔记3-spring AOP实例

假设有以下业务组件,我们使用AOP拦截它的两个业务方法,在方法执行前加入用户验证模块,在方法执行完成后,加入日志记录模块。
public interface Component{
void business1();//业务方法1
void business2();
}
public class ComonentImpl implements Component{
public void business1(){
System.out.println(“执行业务处理方法1”);
}
public void business2(){
System.out.println(“执行业务处理方法2”);
}
}

在Spring使用AOP有三种方式:
(1) 基于API方式。这种方式加入了Spring AOP API,入侵性较强。
一、创建增强,即要加入的代码
//实现spring提供的增强类
public class AdviceBean implements MethodBeforeAdvice,AfterReturningAdvice{
//目标对象业务方法执行前要执行的代码。
public void befor(Method method,Object[]args,Object target)throws Throwable{
validaterUser();//验证用户合法性
}
public void afterReturning(Object return Value,Method method,Object[] args,
Object target)throws Throwable{
writeLogInfo();//写入日志
}
public void validateUser(){
System.out.println(“用户验证通过!”);
}
public void writeLogInfo(){
System.out.println(“日志写入成功!”);
}

}
二、创建切入点类,即要在哪里加入增强,这里直接使用spring提供的切入点实现类,如:NameMatchMethodPointcut
三、创建切面封装类,包装切入点和增强,这里直接使用spring提供的实现类,如:
DefaultPointcutAdvisor
四、创建代理类,这里直接使用spring提供的代理工厂类负责创建。
五、配置以上资源
<!—以下例子的类省略了包路径,实际中要加入-->
<bean id="targetBean" class="...ComponentImpl"/>
<bean id="adviceBean" class="...AdviceBean"/>
<!--使用sping AOP API定义切入点 -->
<bean id="pointcutBean"
class="org.springframework.aop.support.NameMatchMethodPointcut">
<property name="mappedName" value="business*"/>
</bean>
<!--使用sping AOP API定义切面,封装切入点和增强-->
<bean id="aspectBean"
class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="adviceBean"/>
<property name="pointcut" ref="pointcutBean"/>
</bean>
<!--使用sping AOP API定义工厂,创建代理-->
<bean id="component" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="targetBean"/>
<property name="interceptorNames" >
<list>
<value>aspectBean</value>
</list>
</property>
</bean>
六、测试
ApplicationContext context=new ClassPathXmlApplicationContext(aop.xml);
Component cp=(Component)context.getBean(“component”);
cp.business1();//测试aop运行结果

(2)基于Schema方式。这种方式使用普通的java对象表示切入模块,易于移植。它使用配置文件定义增强、切入点、切面。这种方式需要AspectJ框架的支持,要在lib中加入aspectjweaver.jar包(spring-aop.jar包含了该包)
一、创建要切入的模块
public class AspectBean{
public void validateUser(){
System.out.println(“用户验证通过!”);
}
public void writeLogInfo(){
System.out.println(“日志写入成功!”);
}
}

二、使用配置文件定义切入点、增强、切面
<!-- 定义代表切面的java对象-->
<bean id="aspectBean" class="….AspectBean"/>
<aop:config>
<!-- 定义切面-->
<aop:aspect id="aspectDemo" ref="aspectBean">
<!--定义切入点-->
<aop:pointcut id="somePointcut" expression_r_r_r=
"execution(* com.acon.aop.domain.Component.business*(..))"/>
<!--定义切入点上的增强-->
<aop:before pointcut-ref="somePointcut" method="validateUser"/>
<aop:after-returning pointcut-ref="somePointcut"
method="writeLogInfo"/>
</aop:aspect>
</aop:config>
<!--定义组件-->
<bean id="component" class="com.acon.aop.domain.ComponentImpl"/>

三、测试(内容同使用上一节,略)

注意:
a.由于使用了<aop>元素,要修改此文件声明,即:
在<beans>中加入“xmlns:aop="http://www.springframework.org/schema/aop"”
并在”xsi:shemaLocation”中指定AOP配置的schema地址:
“http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd”
b. execution(* )”*”号后面是空格,否则出” Pointcut is not well-formed: expecting”错误

(3)使用AspectJ注解支持。基于注解需要jdk1.5支持,由于切面封装模块是POJO,这种方式不依赖Spring框架。这种方式要引入AspectJ框架相关包-aspectjweaver.jar,由于spring底层使用运行时字节码生成机制,还要相入asm-x.jar和asm-commons-x.jar等(这些包都包含在spring.aop.jar中了,在这里说明,只是告诉大家这些包是用来干什么用的)
一、定义切面
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
@Aspect
public class AspectAnnotationBean{
//定义切入点
@Pointcut(“execution(*com.acon.aop.domain.Component.business*(..))”)
public void somePointcut(){}
//在切入点上加入增强,”*”后有空格
@Pointcut("execution(* com.acon.aop.domain.Component.business*(..))")
public void validateUser(){
System.out.println(“用户验证通过!”);
}
@After(“somePointcut()”)
public void writeLogInfo(){
System.out.println(“写入日志成功!”);
}
}
二、配置切面
<!—定义切面模块-->
<bean id=”aspectBean” class=”….AspectAnnotationBean”/>
<!—使用@AspectJ自动代理-->
<aop:aspectj-autoproxy/>
<!--定义组件-->
<bean id="component" class="com.acon.aop.domain.ComponentImpl"/>

转自:http://xu20cn.blog.51cto.com/274020/243208

posted @ 2011-12-26 15:36  agile_work  阅读(685)  评论(0编辑  收藏  举报