Spring之使用AOP缘由(2-动态代理实现)

zrl00 2015-07-12

为了解决原始实现中存在的问题,下面考虑使用动态代理来实现。

代理设计模式的原理

使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。


Spring之使用AOP缘由(2-动态代理实现)
  

类图
Spring之使用AOP缘由(2-动态代理实现)
 

实现

package xyz.huning.spring4.aop.calculator;

import org.springframework.stereotype.Component;

@Component
public class PureCalculator implements ICalculator {

	@Override
	public double add(double x, double y) {
		System.out.println("execute method add ...");
		return x + y;
	}

	@Override
	public double sub(double x, double y) {
		System.out.println("execute method sub ...");
		return x - y;
	}

	@Override
	public double mul(double x, double y) {
		System.out.println("execute method mul ...");
		return x * y;
	}

	@Override
	public double div(double x, double y) {
		System.out.println("execute method div ...");
		return x / y;
	}

}
package xyz.huning.spring4.aop.calculator.proxyimpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import xyz.huning.spring4.aop.calculator.ICalculator;

public class CalculatorLogProxy {

	private ICalculator target;

	public CalculatorLogProxy(ICalculator target)
	{
		this.target = target;
	}
	
	public ICalculator getProxy()
	{
		ClassLoader classLoader = target.getClass().getClassLoader();
		Class<?>[] interfaces = target.getClass().getInterfaces(); 
		
		/**
		 * proxy:   正在返回/执行的代码,一般不在invoke方法中使用
		 * method:  正在执行的方法
		 * args:    正在执行方法的参数
		 * 
		 */
		InvocationHandler handler = new InvocationHandler()
		{
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println("before: " + "[x=" + args[0] + ", y=" + args[1] + "]");
				Object result = method.invoke(target, args);
				System.out.println("after: " + "[x=" + args[0] + ", y=" + args[1] + "]");
				return result;
			}
			
		};
		return (ICalculator)Proxy.newProxyInstance(classLoader, interfaces, handler);
	}
	
}
package xyz.huning.spring4.aop.calculator.proxyimpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

import xyz.huning.spring4.aop.calculator.ICalculator;

public class CalculatorValidateProxy {

	private ICalculator target;

	public CalculatorValidateProxy(ICalculator target)
	{
		this.target = target;
	}
	
	public ICalculator getProxy()
	{
		ClassLoader classLoader = target.getClass().getClassLoader();
		Class<?>[] interfaces = target.getClass().getInterfaces(); 
		
		InvocationHandler handler = new InvocationHandler()
		{
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				validate(args);
				Object result = method.invoke(target, args);
				return result;
			}
			
		};
		return (ICalculator)Proxy.newProxyInstance(classLoader, interfaces, handler);
	}
	
	private void validate(Object[] args)
	{
		System.out.println("validate parameter: " + Arrays.toString(args));
	}
	
}
package xyz.huning.spring4.aop.calculator.proxyimpl;

import xyz.huning.spring4.aop.calculator.ICalculator;
import xyz.huning.spring4.aop.calculator.PureCalculator;

public class Main {

	public static void main(String[] args) {
		
		ICalculator oc2 = new PureCalculator();
		oc2 = new CalculatorLogProxy(oc2).getProxy();
		oc2 = new CalculatorValidateProxy(oc2).getProxy();
		oc2.add(10, 20);
		oc2.sub(30, 10);
		oc2.mul(10, 10);
		oc2.div(20, 10);
		
	}
}

相关推荐