动态代理实现步骤
java动态代理是一种在运行时创建接口代理对象的机制,它允许你在不修改原有代码的情况下,对方法调用进行拦截和处理。
1. 定义接口:首先,你需要定义一个或多个接口,这些接口将被动态代理类实现。这些接口定义了代理对象应该具备的行为。
2. 实现InvocationHandler接口:这个接口中只有一个方法invoke,它负责处理所有代理方法的调用。(可采用匿名内部类的方式书写)
3. 创建代理实例:使用Proxy类的newProxyInstance静态方法来创建代理实例
类加载器(ClassLoader):用于加载代理类和接口的类加载器。
接口数组(Class<?>[] interfaces):代理类实现的接口数组(需要代理哪些)
调用处理器(InvocationHandler):实现了InvocationHandler接口的实例,负责处理所有方法调用。
4. 使用代理对象
动态代理实现计算方法执行耗时
定义代理接口,
动态代理只能为接口创建代理实例
public interface ProxyInte {
void from1ToN(int n) throws InterruptedException;
void NTo1(int n) throws InterruptedException;
public void sort(int []arr);
}
定义代理类,实现接口,重写方法:
public class TestProxy implements ProxyInte{
@Override
public void from1ToN(int n) throws InterruptedException {
for (int i = 0; i < n; i++) {
Thread.sleep(1);
}
}
@Override
public void NTo1(int n) throws InterruptedException {
while (n>=1){
n--;
Thread.sleep(2);
}
}
@Override
public void sort(int []arr){
Arrays.sort(arr);
}
}
创建代理:
/**
* 创建一个动态代理对象,该代理对象将计算方法执行的耗时。
*
* @param target 被代理的对象,它实现了TestProxy接口
* @return 返回一个实现了ProxyInte接口的代理对象
*/
public static ProxyInte createProxy(TestProxy target) {
// 使用Proxy.newProxyInstance方法创建代理对象
ProxyInte proxy = (ProxyInte) Proxy.newProxyInstance(
TestProxy.class.getClassLoader(), // 使用TestProxy接口的类加载器
target.getClass().getInterfaces(), // 获取目标对象实现的所有接口new Class[]{ProxyInte.class},这里我只有一个接口
new InvocationHandler() {
/**
* 实现InvocationHandler接口的invoke方法,该方法将拦截所有代理对象的方法调用。
*
* @param proxy 代理对象本身,通常不使用
* @param method 被调用的方法对象
* @param args 被调用方法的参数数组
* @return 返回方法调用的结果
* @throws Throwable 如果方法调用抛出异常,则这里也会抛出
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long start = System.currentTimeMillis(); // 记录方法开始执行的时间
Object result = method.invoke(target, args); // 调用目标对象的方法
long end = System.currentTimeMillis(); // 记录方法结束执行的时间
// 打印方法名和执行耗时
System.out.println(method.getName() + "执行耗时" + (end - start) + "ms");
return result; // 返回方法调用的结果
}
}
);
return proxy; // 返回创建的代理对象
}
}
创建测试类运行(使用):
public class test {
public static void main(String[] args) throws InterruptedException {
ProxyInte p = MyProxy.createProxy(new TestProxy());
p.from1ToN(100);
p.NTo1(120);
Random r = new Random();
int[] arr = new int[5000];
for (int i = 0; i < arr.length; i++) {
arr[i]=r.nextInt(0,1000);
}
p.sort(arr);
}
}
cglib代理
通过父子继承关系来创建代理:
代理类是子类型
目标方法是父类类型(方法和类不能为final关键字修饰)
Enhancer.create(
父类型,
Callback
)
JDK代理
newProxyInstance(
)