需求:
有一个自己创建的类Calculater,里面有加、减、乘、除方法。要求在不改变原方法的基础上对各个方法实现增强(打印日志)
原理:
java中的Proxy类,有一个newProxyInstance(loader, interfaces, h),可以创建一个代理类,在其中可以执行被代理类的方法,并可以是现在方法前后对方法做增强处理。
参数说明:
loader - 定义代理类的类加载器
interfaces - 代理类要实现的接口列表
h - 指派方法调用的调用处理程序
参考源码:
package com.gang.inter;
public interface Calculator {
public int add(int i,int j);
public int sub(int i,int j);
public int mul(int i,int j);
public int div(int i,int j);
}
package com.gang.impl;
import com.gang.inter.Calculator;
public class MyCalculator implements Calculator {
@Override
public int add(int i, int j) {
//手动为方法添加日志
//LogUtils.startLog(i,j,"加法");
int result;
result=i+j;
return result;
}
@Override
public int sub(int i, int j) {
int result;
result=i-j;
return result;
}
@Override
public int mul(int i, int j) {
int result;
result=i*j;
return result;
}
@Override
public int div(int i, int j) {
int result;
result=i/j;
return result;
}
}
package com.gang.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.gang.inter.Calculator;
import com.gang.utils.LogUtils;
public class CalculatorProxy {
public static Calculator getPoxy(Calculator myCalcultor) {
//为执行Proxy.newProxyInstance(loader, interfaces, h),三个参数赋值
ClassLoader loader = myCalcultor.getClass().getClassLoader();
Class<?>[] interfaces = myCalcultor.getClass().getInterfaces();
InvocationHandler h = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//对原方法添加日志
Object result=null;
try {
LogUtils.startLog(method, args);
result=method.invoke(myCalcultor, args);
LogUtils.endLog(method, result);
} catch (Exception e) {
LogUtils.exceptionLog(method, e);
}finally{
LogUtils.finallyLog(method);
}
return result;
}
};
//生成代理对象
Calculator proxy=(Calculator) Proxy.newProxyInstance(loader, interfaces, h);
return proxy;
}
}
package com.gang.utils;
import java.lang.reflect.Method;
import java.util.Arrays;
public class LogUtils {
public static void startLog(Method method,Object... objects){
System.out.println("【"+method.getName()+"】执行开始了,他的参数为【"+Arrays.asList(objects)+"】");
}
public static void endLog(Method method,Object... objects){
System.out.println("【"+method.getName()+"】执行结束了,他的结果为【"+Arrays.asList(objects)+"】");
}
public static void exceptionLog(Method method,Exception e){
System.out.println("【"+method.getName()+"】执行出错了,错误信息为【"+e.getCause()+"】");
}
public static void finallyLog(Method method){
System.out.println("【"+method.getName()+"】最终执行结束了");
}
}
package com.gang.test;
import org.junit.Test;
import com.gang.impl.MyCalculator;
import com.gang.inter.Calculator;
import com.gang.proxy.CalculatorProxy;
public class CalculatorTest {
@Test
public void test(){
Calculator myCalcultor=new MyCalculator();
//int result=myCalcultor.add(2, 4);
//采用动态代理为方法添加日志
Calculator proxy=CalculatorProxy.getPoxy(myCalcultor);
proxy.add(2, 4);
proxy.div(2, 1);
}
}
运行结果: