1. 程式人生 > >基於代理的spring aop中多種通知實現

基於代理的spring aop中多種通知實現

不需要引入額外的jar包,只需引入需要模組的spring內部jar包即可.

介面結構

標註的都是標記介面,其中大多數有明確約定的介面實現,只有異常通知介面沒有,但有其預設約定.

Advice spring aop通知的頂層標記介面
MethodBeforeAdvice 約定前置通知的介面
AfterReturningAdvice 約定返回通知的介面
因後置通知無約定介面,可使用其進行後置通知.
ThrowsAdvice

約定異常通知的介面

無具體約定,但有預設的實現規範.

MethodInterceptor 約定環繞通知的介面
ProxyFactory spring內建的建立代理的工具類

目標物件類

package siye;
public class TargetObj
{
	public void work()
	{
		System.out.println("work......");
	}
	public void throwOwn()
	{
		throw new RuntimeException();
	}
}

測試前置通知的實現

package siye;
import java.lang.reflect.Method;
import org.aopalliance.aop.Advice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
public class UnitTestMethodBeforeAdviceImpl
{
	public static void main(String[] args)
	{
		TargetObj targetObj = new TargetObj();
		Advice adviceImpl = new MethodBeforeAdviceImpl();
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTarget(targetObj);
		proxyFactory.addAdvice(adviceImpl);
		TargetObj obj = (TargetObj) proxyFactory.getProxy();
		obj.work();
	}
}
class MethodBeforeAdviceImpl implements MethodBeforeAdvice
{
	@Override
	public void before(Method method, Object[] args, Object target)
			throws Throwable
	{
		System.out.println("方法即將被呼叫");
	}
}

測試返回通知(後置通知)的實現

package siye;
import java.lang.reflect.Method;
import org.aopalliance.aop.Advice;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.framework.ProxyFactory;
public class UnitTestAfterReturningAdviceImpl
{
	public static void main(String[] args)
	{
		TargetObj targetObj = new TargetObj();
		Advice adviceImpl = new AfterReturningAdviceImpl();
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTarget(targetObj);
		proxyFactory.addAdvice(adviceImpl);
		TargetObj obj = (TargetObj) proxyFactory.getProxy();
		obj.work();
	}
}
class AfterReturningAdviceImpl implements AfterReturningAdvice
{// 後置通知暫未找到藉口,可用此介面替代.
	@Override
	public void afterReturning(Object returnValue, Method method,
			Object[] args, Object target) throws Throwable
	{
		System.out.println("方法已返回值,是" + returnValue);
	}
}

測試異常通知的實現

package siye;
import org.aopalliance.aop.Advice;
import org.junit.Test;
import org.springframework.aop.ThrowsAdvice;
import org.springframework.aop.framework.ProxyFactory;
class UnitTest
{
}
/*
 * ThrowsAdvice是標記介面
 * 在aop包中,不同其他通知介面,沒有約定的方法.
 * 原始碼文件中有預設約定.
 * 
 * 規定的格式
 * void afterThrowing([Method, args, target], ThrowableSubclass);
 * 前三個引數是可選的,但必須一同出現,第四個引數是必選的.
 * e.g.
 * public void afterThrowing(Exception ex)
 * public void afterThrowing(RemoteException)
 * public void afterThrowing(Method method, Object[] args, Object target,
 * Exception ex)
 * public void afterThrowing(Method method, Object[] args, Object target,
 * ServletException ex)
 * 
 * The first three arguments are optional, and only useful if we want further
 * information about the joinpoint, as in AspectJ after-throwing advice.
 */
public class UnitTestThrowsAdviceImpl implements ThrowsAdvice
{// 此類必須標記為public
	// IllegalAccessException: Class
	// org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor can not
	// access a member of class
	public void afterThrowing(Exception e)
	{
		System.out.println("方法丟擲異常,型別是" + e.toString());
	}
	// 單元測試
	@Test
	public void test()
	{
		TargetObj targetObj = new TargetObj();
		Advice adviceImpl = new UnitTestThrowsAdviceImpl();
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTarget(targetObj);
		proxyFactory.addAdvice(adviceImpl);
		TargetObj obj = (TargetObj) proxyFactory.getProxy();
		try
		{
			obj.throwOwn();
		} catch (Exception e)
		{
		}
	}
}

測試環繞通知的實現

package siye;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
public class UnitTestMethodInterceptorImpl
{
	public static void main(String[] args)
	{
		TargetObj targetObj = new TargetObj();
		Advice interceptorImpl = new MethodInterceptorImpl();
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTarget(targetObj);
		proxyFactory.addAdvice(interceptorImpl);
		TargetObj obj = (TargetObj) proxyFactory.getProxy();
		obj.work();
	}
}
class MethodInterceptorImpl implements MethodInterceptor
{
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable
	{
		System.out.println("方法即將開始");
		// 通過反射機制呼叫目標的方法
		Object object = invocation.proceed();
		System.out.println("方法執行結束");
		return object;
	}
}