您的位置:首页 > 编程语言 > Java开发

Aop_面向切面编程(2)_spring的aop实现

2012-07-07 18:36 507 查看
Aop的三个关键概念简介

Aop思想有三个重要概念:Pointcut,Advice,Advisor。

Pointcut(切入点):

在pointcut之前先说明一个概念:joinPoint(连接点)。Join-Point指程序运行中的某一个阶段点,比如某个方法的调用,异常的抛出。比如上例中的register方法就是一个jion-point。

Pointcut是jion-point的集合,他是程序中需要注入Advice的位置的集合。他指明Advice什么情况下被触发。Spring中用org.springframework.aop.Pointcut接口表示pointcut概念。

Advice(通知)

Advice是某个连接点采用的处理逻辑,也就是向连接点注入的代码。上例中日志输出的代码就是一个advice。

Advisor(通知者)

Advisor是advice和pointcut的配置器,它包括二者。

Spring的三种切入点实现

静态切入点

静态切入点使用类名和方法描述切入点。org.sprinframework.aop.support.RegexpMethodPoint是一个静态切入点的实现。这是一个通用的正则表达式切入点。

(这个切入点的实现使用Jakarta ORO,依赖jakarta-oro-2.0.8.jar)

(Jakarta-ORO是最全面以及优化得最好的正则表达式API之一,Jakarta-ORO库以前叫做OROMatcher,是由Daniel F. Savarese

编写,后来他将其赠与Jakarta Project。是面向J***A的正则表达式库。)

使用这个切入点的一个案例是:

<bean id="registerPointCut" class="org.springframework.aop.support.RegexpMethodPointcut">

<property name="pattern">

<list>

<value>.*save*.</value>

<value>.*save*.</value>

</list>

</bean>

此配置含义是:所有以sava和do开头的方法为切入点

动态切入点

动态切入点和静态切入点的唯一不同为,动态切入点可以依赖方法参数确定。

Spring有个内建的动态切入点:控制流切入点。

大多数情况下使用静态切入点,极少使用动态切入点。

自定义切入点

Spring中切入点是java类,而不是语言特性,因此可以自定义切入点。

Spring的Advice(通知)

Spring提供了5种Advice的实现类型。Interceptor Around, Before, After Running, Throw, Introduction。他们分别pointcut的前后,前,后,抛出异常,条用之后执行。

Interceptor Around

会在jionpiont前执行,上例中的日志代理类就是一个Interceptor Arouond。

实现Interceptor Around需要实现MehodInterceptor接口:

Public class logInterceptor implements MehodInterceptor{

Public Object invoke(MethodInvocation invocation)throws Throwable{

System.out.println("正在审核...");

Object result = invocation.proceed();

System.out.println("注册完毕");

Return result;

}

}

Before

实现MethodBeforeAdvice接口:

Public class logAdvice implements MethodBeforeAdvice{

Public void before(Method m , Object[] args ,Object target)throws Trowable{

System.out.println("开始审核数据...");

}

}

After Running

实现AfterRunningAdvice接口:

Public class logAdvice implements AfterRuningAdvice {

Public void afterRunning(Method m,Object[] args,Object target)throw Throwable{

System.out.println("注册完毕");

}

}

Throw

实现ThrowAdvice接口:

Public class logThrowAdvice implements ThrowsAdvice{

Public void afterThowing(RemoteException ex)throws Throwable{

System.out.println("审核数据出现异常请检查"+ex);

}

}

Introduction

实现IntroductionAdvice接口和IntroductinoInterceptor接口

Spring的Advisor

org.springframework.aop.support.DefaultPointcutAdvisor是最通用的Advisor类。

使用PorxyFactoryBean创建Aop代理

org.springframework.aop.framework.ProxyFactoryBean是创建代理的最基本的方式。

代理目标类的所有方法

<beans>

<!--Advice-->

<bean id="logAdvice" class="com.test.LogAround" />

<!--被代理的目标类-->

<bean id="register" class="com.test.RegisterImpl"/>

<bean id="logProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

<!--要代理的接口-->

<property name="proxyInterface">

<value>com.test.Register<value>

</property>

<!--要代理的目标类-->

<property name="target">

<ref="register"/>

</property>

<!--advice-->

<property name="interceptorNames">

<list>

<value>logAdvice</value>

</list>

</property>

</bean>

</beans>

代理目标类的指定方法

<beans>

<!--Advice-->

<bean id="logAdvice" class="com.test.LogAround" />

<!--被代理的目标类-->

<bean id="register" class="com.test.RegisterImpl"/>

<!--advisor-->

<bean id="logAdvisor" class="org.springframework.aop.support.RegexpMethodPointAdvisor">

<!--指定advice-->

<property name="advice">

<ref bean="lgoAdivce"/>

</property>

<!--指定代理方法-->

<property name="pattern">

<value>.*log.*</value>

</property>

</bean>

<bean id="logProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

<!--要代理的接口-->

<property name="proxyInterface">

<value="com.test.Register"><value>

</property>

<!--要代理的目标类-->

<property name="target">

<ref="register"/>

</property>

<!--Advisor-->

<property name="interceptorNames">

<list>

<value>logAdvisor</value>

</list>

</property>

</bean>

</beans>

把输出日志的实例改成由spring的Aop特性实现

使用InterceptotionAround 通知实现

/**

*

* @file:LogAdvice.java

* @discript: 输出日志切面的通知类实现MehodInterceptor接口,在jionpoint的前后执行

* @author: yanwushu

* @date:2012-6-29

*

*/

public class LogAdvice implements MethodInterceptor{

private Logger logger = Logger.getLogger(this.getClass().getName());



@Override

public Object invoke(MethodInvocation mi) throws Throwable {

logger.log(Level.INFO,"开始审核数据...");

try{



Object result = mi.proceed();

return result;

}finally {

logger.log(Level.INFO,"审核结束");

}

}

}

先实现advice。注:MethodInvocation可以获取方法的参数,名称等。

日志接口、实现类不用改。

配置文件applicationContext.xml

<bean id="register" class="util.RegisterImpl"></bean>

<bean id="logAdvice" class="advice.LogAdvice"></bean>

<bean id="logerProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="proxyInterfaces">

<value>util.Register</value>

</property>

<property name="target">

<ref bean="register"/>

</property>

<property name="interceptorNames">

<list>

<value >logAdvice</value>

</list>

</property>

</bean>

测试类:

public static void main(String[] args) {

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

Register register = (Register) ac.getBean("logerProxy");

register.register("张三");

}

本例完整代码下载 http://download.csdn.net/detail/yanwushu/4416217
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: