AOP编程之后置通知、环绕通知、异常通知、引入通知

1、后置通知

        当需要在街口方法调用后统一处理事务,如关闭资源,可以使用后置通知。Spring中的后置通知(After Returning advice)必须实现 org.springframework.aop.AfterReturningAdvice 接口,如下:

public class MyAfterReturningAdvice implements AfterReturningAdvice {

	@Override
	public void afterReturning(Object returnValue, Method method, Object[] args, Object tagert) throws Throwable {
		// TODO Auto-generated method stub
        System.out.println("close resource");
	}

}

2、环绕通知

    当需要在调用接口方法前和调用方法后统一处理事务,可以使用环绕通知。实现环绕通知的MethodInterceptor应当实现下面的接口:

package com.mdd.aop;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyMethodInterceptor implements MethodInterceptor {

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("调用方法前执行");
		Object obj= arg0.proceed();
		System.out.println("调用方法后执行");
		return obj ;
	}

}

该接口同前两种通知有两个重要区别:1.该通知能够控制目标方法是否真的被调用。通过invocation.proceed()方法来调用。

该通知可以控制返回的对象。可以返回一个与proceed()方法返回对象完全不同的对象。但要谨慎使用。


3、异常通知

    当目标对象的方法出现异常,会统一在异常通知处理。如果连接点抛出异常,异常通知(throws advice)将在连接点返回后被调用。

package com.mdd.aop;

import java.lang.reflect.Method;

import org.springframework.aop.ThrowsAdvice;

public class MyThrowsAdvice implements ThrowsAdvice {
	
	public void afterThrowing(Method m, Object[] os, Object 
			target, Exception e)
	{
		System.out.println("出大事了"+ e.getMessage());
	}

}

4、引入通知

    若只需要目标对象指定的方法织入特定的通知,而不是所有的方法,则需要配置引入通知。通过org.springframework.aop.support.NameMatchMethodPointcutAdvisor来进行配置引入通知。


5、各种通知的配置

接口1:Test2ServiceInter.java

package com.mdd.aop;

public interface Test2ServiceInter {
	public void sayBye();

}


接口2:TestServiceInter.java

package com.mdd.aop;


public interface TestServiceInter {
	public void sayHello();
	

}


实现类:Test1Service.java,实现了上面两个接口

package com.mdd.aop;


public class Test1Service implements TestServiceInter, Test2ServiceInter{

	private String userName;
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	private int age;
	@Override
	public void sayHello() {
		// TODO Auto-generated method stub
		System.out.println("Hello "+userName +"Age " +age);
//		int i = 9/0;
//		System.out.println(i);
	}
	@Override
	public void sayBye() {
		// TODO Auto-generated method stub
		System.out.println("ByeBye "+userName +"Age " +age);
	}

}


通知的配置如下:

<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:context="http://www.springframework.org/schema/context"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
				
<bean id="test1Service" class="com.mdd.aop.Test1Service">
<property name="userName">
<value>madingding</value>
</property>
<property name="age" value="25"/>
</bean>
<bean id="myAfterReturningAdvice" class="com.mdd.aop.MyAfterReturningAdvice"/>
<!--配置环绕通知  -->
<bean id="myMethodInterceptor" class="com.mdd.aop.MyMethodInterceptor"/>
<bean id ="myThrowsAdvice" class="com.mdd.aop.MyThrowsAdvice"/>
<!--定义后置通知的切入点  -->
<!--定义只对代理接口的sayHello方法织入后置通知,其他方法不会有后置通知 -->
<bean id="myMethodAfterAdviceFilter" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="myAfterReturningAdvice"/>
<property name="mappedNames">
	<list>
	<value>sayHello</value>
	</list>
</property>
</bean>

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


<!--代理接口集  -->
<property name="proxyInterfaces">
	<list>
	     <value>com.mdd.aop.TestServiceInter</value>
	     <value>com.mdd.aop.Test2ServiceInter</value>
	</list>
</property>

<!-- 将通知织入到代理对象 -->
<property name="interceptorNames">
    <!-- 植入后置通知 -->
    <list>
    <value>myThrowsAdvice</value>
    <!--使用自定义切入点来控制后置通知 ,通过引入通知来控制某个方法织入的通知 -->
	<value>myMethodAfterAdviceFilter</value>
	<value>myMethodInterceptor</value>
	</list>
</property>

<!-- 配置被代理对象 -->
<property name="target" ref="test1Service"/>


</bean>


</beans>


执行结果如下,从结果可以看出,通过引入通知过滤之后,只有sayHello方法织入了后置通知,其他方法没有后置通知。

调用方法前执行
Hello madingdingAge 25
调用方法后执行
close resource
*********************
调用方法前执行
ByeBye madingdingAge 25
调用方法后执行




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值