介绍动态代理的使用。

使用场景:

业务需要加上“开始...结束...”类型日志,如果在每个业务中都加上日志代码会很繁琐,如果使用动态代理就方便多了。


详细:

ArithmeticCalculator.java:

package com.shuoeasy.test;

/**
 * 定义计算器接口
 *
 */
public interface ArithmeticCalculator {
	double add(double num1, double num2);
	double sub(double num1, double num2);
	double mul(double num1, double num2);
	double div(double num1, double num2);
}

ArithmeticCalculatorImpl.java

package com.shuoeasy.test;

/**
 * 业务类不加日志,使用代理方式实现日志
 *
 */
public class ArithmeticCalculatorImpl implements ArithmeticCalculator{

	public double add(double num1, double num2) {
		double result = num1 + num2;
		return result;
	}

	public double sub(double num1, double num2) {
		double result = num1 - num2;
		return result;
	}

	public double mul(double num1, double num2) {
		double result = num1 * num2;
		return result;
	}

	public double div(double num1, double num2) {
		double result = num1 / num2;
		return result;
	}

}

ArithmeticCalculatorLoggingProxy.java

package com.shuoeasy.test;

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

import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;
 
/**
 * 动态代理
 */
public class ArithmeticCalculatorLoggingProxy {
	private ArithmeticCalculator target;
	
	public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) {
		this.target = target;
	}

	public ArithmeticCalculator getLogingProxy(){
		ArithmeticCalculator proxy = null;
		
		// 代理对象由哪一个类加载器负责加载
		ClassLoader loader = target.getClass().getClassLoader();
		// 代理对象的类型,既其中有哪些方法
		Class[] interfaces = new Class[]{ArithmeticCalculator.class};
		// 当调用带了对象其中的方法是,该执行的代码
		InvocationHandler invocationHandler = new InvocationHandler() {
			/**
			 * proxy:正在返回的代理对象,一般情况下咋invoke方法中都不适用该对象。
			 * method:正在被调用的方法。
			 * args:调用方法是传入的参数。
			 */
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				String methodName = method.getName();
				// 日志
				System.out.println("The method " + methodName + " begin with " + Arrays.asList(args));
				// 执行方法
				Object result = method.invoke(target, args);
				// 日志
				System.out.println("The method " + methodName + " end with " + result);
				return result;
			}
		};
		
		proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, invocationHandler);
		return proxy;
	}
}

Main.java:

package com.shuoeasy.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	public static void main(String[] args) {
		// 使用动态代理方式加日志
		ArithmeticCalculator target = new ArithmeticCalculatorImpl();
		ArithmeticCalculator proxy = new ArithmeticCalculatorLoggingProxy(target).getLogingProxy();
		System.out.println("结果" + proxy.add(2, 3) + "\n");
		System.out.println("结果" + proxy.sub(2, 3) + "\n");
		System.out.println("结果" + proxy.mul(2, 3) + "\n");
		System.out.println("结果" + proxy.div(2, 3) + "\n");
	}
}

输出:

The method add begin with [2.0, 3.0]

The method add end with 5.0

结果5.0


The method sub begin with [2.0, 3.0]

The method sub end with -1.0

结果-1.0


The method mul begin with [2.0, 3.0]

The method mul end with 6.0

结果6.0


The method div begin with [2.0, 3.0]

The method div end with 0.6666666666666666

结果0.6666666666666666


你可能感兴趣的文章