动态代理
接口类
package com.czl.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);
}
接口实现类(被代理类)
public class MyMathCalculator implements Calculator{
@Override
public int add(int i, int j) {
int result = i + j;
return result;
}
@Override
public int sub(int i, int j) {
int result = i - j;
return result;
}
@Override
public int mul(int i, int j) {
//方法的兼容性;
int result = i * j;
return result;
}
@Override
public int div(int i, int j) {
int result = i / j;
return result;
}
}
日志类
import java.lang.reflect.Method;
import java.util.Arrays;
public class LogUtils {
public static void logStart(Method method,Object... args){
System.out.println("【"+method.getName()+"】方法开始执行,用的参数列表【"+Arrays.asList(args)+"】");
}
public static void logReturn(Method method,Object result){
System.out.println("【"+method.getName()+"】方法正常执行完成,计算结果是:"+result);
}
public static void logException(Method method, Exception e) {
System.out.println("【"+method.getName()+"】方法执行出现异常了,异常信息是:"+e.getCause()+";这个异常已经通知测试小组进行排查");
}
public static void logEnd(Method method) {
System.out.println("【"+method.getName()+"】方法最终结束了");
}
}
动态代理(生成代理对象)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import com.atguigu.inter.Calculator;
import com.atguigu.utils.LogUtils;
/**
* 帮Calculator.java生成代理对象的类
* Object newProxyInstance
* (ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
*
* @author lfy
*
*/
public class CalculatorProxy {
/**
* 为传入的参数对象创建一个动态代理对象
* @param calculator
* @return
*
* Calculator calculator:被代理对象;(宝宝)
* 返回的:宋喆
*/
public static Calculator getProxy(final Calculator calculator) {
// TODO Auto-generated method stub
//方法执行器。帮我们目标对象执行目标方法
InvocationHandler h = new InvocationHandler() {
/**
* Object proxy:代理对象;给jdk使用,任何时候都不要动这个对象
* Method method:当前将要执行的目标对象的方法
* Object[] args:这个方法调用时外界传入的参数值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 利用反射执行目标方法
//目标方法执行后的返回值
//System.out.println("这是动态代理将要帮你执行方法...");
Object result = null;
try {
LogUtils.logStart(method, args);
result = method.invoke(calculator, args);
LogUtils.logReturn(method, result);
} catch (Exception e) {
LogUtils.logException(method,e);
}finally{
LogUtils.logEnd(method);
}
//返回值必须返回出去外界才能拿到真正执行后的返回值
return result;
}
};
Class<?>[] interfaces = calculator.getClass().getInterfaces();
ClassLoader loader = calculator.getClass().getClassLoader();
//Proxy为目标对象创建代理对象;
Object proxy = Proxy.newProxyInstance(loader, interfaces, h);
return (Calculator) proxy;
}
}
测试类
public class AOPTest {
/**
* 有了动态代理,日志记录可以做的非常强大;而且与业务逻辑解耦
*
* jdk默认的动态代理,如果目标对象没有实现任何接口,是无法为他创建代理对象的;
*
*/
@Test
public void test() {
Calculator calculator = new MyMathCalculator();
calculator.add(1, 2);
calculator.div(2, 1);
System.out.println("[==========]");
//如果是拿到了这个对象的代理对象;代理对象执行加减乘除;
Calculator proxy = CalculatorProxy.getProxy(calculator);
//com.sun.proxy.$Proxy2也是实现了Calculator接口
//代理对象和被代理对象唯一能产生的关联就是实现了同一个接口
System.out.println(Arrays.asList(proxy.getClass().getInterfaces()));
proxy.add(2, 1);
proxy.div(2, 0);
}
}