基于代理的spring aop中多种通知实现

版权声明:仅供学习交流使用 https://blog.csdn.net/drxRose/article/details/84831408

不需要引入额外的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;
	}
}

猜你喜欢

转载自blog.csdn.net/drxRose/article/details/84831408