Study
动态代理分析
功能
- 特点: 字节码可以随用随创建,随用随加载
- 作用: 不写该源码的基础上对方法增强
- 分类:
基于接口的动态代理
- 类: Proxy
- 提供者JDK
- 如何创建代理对象?
- 使用Proxy类中的++newProxyInstance++方法
- 创建被代理对象的要求:
- newProxyInstance方法的参数
- classLoader
- 用于加载代理对象字节码的,和被代理对象使用相同的类加载器。
- Class[]
- 让代理对象和被代理对象有相同的方法。(两个同一实现一个接口)
- InvocationHandler:对方增强
Iprodcer o = (Iprodcer)Proxy.newProxyInstance(prodcer.getClass().getClassLoader(), prodcer.getClass().getInterfaces(),
new InvocationHandler() {
/**
* 执行被代理对象的任何接口方法都会经过次方法
* @param proxy:代理对象的引用
* @param method:调用的方法
* @param args:方法参数
* @return: 和原方法一致返回值
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("saleProduct")){
return method.invoke(prodcer, (Double)args[0]*0.8);
}
return null;
}
});
基于子类的动态代理
- 类: ++Enhancer++
- 第三方
- 如何创建代理对象?
- 使用Enhancer类中的++create++方法
- 创建被代理对象的要求:
- create方法的参数
- Class
- 用于加载代理对象字节码的,和被代理对象使用相同的类加载器。
- CallBack:增强
- 一般写的子接口的实现类:++MthodIntercepter++
1. 引入cglib
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_3</version>
</dependency>
</dependencies>
2. 创建被代理类
package com.atjianyi.da;
/**
* @author 简一
* @className Producer
* @Date 2021/1/26 14:17
**/
public class Producer {
public void salerProduct(double money){
System.out.println("销售了+"+money);
}
}
3. 创建代理对象并调用执行
public static void main(final String[] args) {
//创建被代理类的对象
final Producer producer = new Producer();
Producer cglibPro = (Producer)Enhancer.create(producer.getClass(), new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//判断方法
double money = (Double) objects[0];
if ("salerProduct".equals(method.getName())) {
return method.invoke(producer, money* 0.8);
}
return null;
}
});
cglibPro.salerProduct(1000);
}