动态代理
代理模式
为其他对象提供一个代理以控制对某个对象的访问。代理类主要负责为委托了(真实对象)预处理消息、过滤消息、传递消息给委托类,代理类不现实具体服务,而是利用委托类来完成服务,并将执行结果封装处理。
动态代理
动态代理,利用反射机制在 运行时 创建代理类,接口、被代理类不改变。
1、使用 jdk 动态代理
/**
* jdk动态代理:基于接口
* @author aaaa
*/
public class CalculatorTest {
@Test
public void fun() {
//目标对象
CalculatorService calculatorService = new CalculatorServiceImpl();
//为创建代理对象准备数据
//1、类加载器
ClassLoader classLoader = calculatorService.getClass().getClassLoader();
//2、目标对象实现的接口
Class<?>[] interfaces = calculatorService.getClass().getInterfaces();
//3、调用方法的处理器
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj = null;
//如果是需要增强的方法
if ("add".equals(method.getName())) {
//增加功能
System.out.println("开启日志记录================");
//执行目标对象的方法
obj = method.invoke(calculatorService, args);
System.out.println("结束日志记录=================");
} else {
//直接执行目标对象的方法,不做加强操作
obj = method.invoke(calculatorService, args);
}
return obj;
}
};
//创建目标对象的代理对象
CalculatorService proxy = (CalculatorService) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
proxy.add(1,2);
//输出目标对象和代理对象
System.out.println("目标对象:" + calculatorService.getClass());
System.out.println("代理对象:" + proxy.getClass());
}
}
2、使用 cglib 动态代理
/**
* 使用cglib动态代理
* 原理是修改字节码文件,添加功能
*/
public class CglibTest {
@Test
public void fun() {
//目标对象
CalculatorService calculatorService = new CalculatorService();
//准备工作---------------------------
//设置代理对象的业务方法拦截操作
MethodInterceptor methodInterceptor = new MethodInterceptor() {
/*
* proxy:表示动态代理对象
* method:表示调用的方法全名
* args:表示调用方法的参数
* methodProxy:表示调用父类方法
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object result = null;
//判断是不是需要代理的方法
if ("add".equals(method.getName())) {
//添加增强功能
System.out.println("开始日志记录============");
//子类去调用父类的业务方法
result = methodProxy.invokeSuper(proxy, args);
System.out.println("日志记录结束===========");
} else {
result = methodProxy.invokeSuper(calculatorService, args);
}
return result;
}
};
Enhancer enhancer = new Enhancer();
//设置父类对象的类型
enhancer.setSuperclass(calculatorService.getClass());
//设置父类对象方法的拦截
enhancer.setCallback(methodInterceptor);
//准备工作---------------------------
//创建目标对象的代理对象
CalculatorService proxy = (CalculatorService) enhancer.create();
proxy.add(2,3);
//输出目标对象和代理对象
System.out.println("目标对象: " + calculatorService.getClass());
System.out.println("代理对象: " + proxy.getClass());
}
}