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


Aop的三个关键概念简介


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

Pointcut(切入点):

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

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

Advice(通知)

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

Advisor(通知者)

Advisoradvicepointcut的配置器,它包括二者。


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。是面向JAVA的正则表达式库。)

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

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

<property name="pattern">

<list>

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

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

</list>

</bean>

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

动态切入点

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

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

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

自定义切入点

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


SpringAdvice(通知)


Spring提供了5Advice的实现类型。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接口


SpringAdvisor


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>


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


使用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




你可能感兴趣的:(java,spring,AOP,编程,正则表达式,object)