在Java中,包含两种动态代理:
两种动态代理的主要区别:
在学习Springframework 的 AOP模块时,其核心就是动态代理,如果Bean实现了某个接口,那么默认使用的基于Jdk的动态代理,如果Bean没有实现任何接口,那么使用的是Cglib的动态代理。
Jdk动态代理有两个核心类,分别是InvocationHandler(这是个函数式接口)、Proxy(类),这两个类都在java.lang.reflect包下面。这里我就不去讲JDK动态代理的原理了,网上有很多相关博客教程,我这里写了几个工具类供大家使用,直接上代码吧。
定义接口
/**
* Target Object
*
* @author : sungm
* @date : 2020-12-03 15:48
*/
public interface Target {
/**
* doSomething
*/
void doSomething();
}
定义接口的默认实现类
package com.miracle.proxy.jdk;
/**
* @author : sungm
* @date : 2020-12-03 15:49
*/
public class DefaultTarget implements Target {
/**
* doSomething
*/
@Override
public void doSomething() {
System.out.println("基于Java的动态代理");
}
}
工具类一:提供自定义抽象的InvocationHandler类
package com.miracle.reflect.jdk.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 基于JDK的动态代理
*
* @author : sungm
* @date : 2020-12-03 15:38
*/
public abstract class BaseInvocationHandler<T> implements InvocationHandler {
/**
* 目标对象。条件:目标类至少实现一个接口
*/
private T t;
/**
* 获取代理对象
*
* @param t target object
* @return proxy object
*/
public Object getProxy(T t) {
this.t = t;
return Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before(proxy, t, method, args);
@SuppressWarnings("unchecked")
//这里不能调用代理对象proxy, 因为proxy会再次调用该方法,然后就进入死循环了,所以这里必须使用目标对象t
final T invoke = (T) method.invoke(t, args);
after(proxy, t, method, args);
return invoke;
}
/**
* method invoke before call before method;
* @param proxy proxyObject
* @param target targetObject
* @param method method
* @param args args
*/
protected abstract void before(Object proxy, T target, Method method, Object[] args);
/**
* method invoke after call after method;
* @param proxy proxyObject
* @param target targetObject
* @param method method
* @param args args
*/
protected abstract void after(Object proxy, T target, Method method, Object[] args);
/**
* 测试
*
* @param args a
*/
public static void main(String[] args) {
BaseInvocationHandler<Target> invocationHandler = new BaseInvocationHandler<Target>() {
@Override
protected void before(Object proxy, Target target, Method method, Object[] args) {
System.out.println("指定" + method.getName() + "方法执行之前执行当前before方法");
}
@Override
protected void after(Object proxy, Target target, Method method, Object[] args) {
System.out.println("指定" + method.getName() + "方法执行之后执行当前after方法");
}
};
Target target = (Target) invocationHandler.getProxy(new DefaultTarget());
target.doSomething();
}
工具类二:提供JdkProxyUtils
package com.miracle.reflect.jdk.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
* @author : sungm
* @date : 2021-04-09 10:53
*/
public class JdkProxyUtils {
private JdkProxyUtils() {
}
/**
* 推荐使用:代理对象,增强方法一步到位
*
* @param t target object
* @param before before consumer
* @param after after consumer
* @return proxy object
*/
public static <T> Object getProxy(T t, BiConsumer<Method, Object[]> before, BiConsumer<Method, Object[]> after) {
return getProxy(t, getInvocationHandler(t, before, after));
}
/**
*
* @param t target object
* @param ih InvocationHandler instance
* @return proxy object
*/
public static <T> Object getProxy(T t, InvocationHandler ih) {
return Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), ih);
}
/**
* 获取InvocationHandler
*
* @param t target object
* @param before before consumer
* @param after after consumer
* @return InvocationHandler instance
*/
public static <T> InvocationHandler getInvocationHandler(T t, BiConsumer<Method, Object[]> before
, BiConsumer<Method, Object[]> after) {
return (Object proxy, Method method, Object[] args) -> {
//执行before方法
if (Objects.nonNull(before)) {
before.accept(method, args);
}
//执行目标方法
final Object result = method.invoke(t, args);
//执行after方法
if (Objects.nonNull(after)) {
after.accept(method, args);
}
//返回目标方法执行结果
return result;
};
}
public static void main(String[] args) {
Consumer<Object[]> consumer = params -> Optional.ofNullable(params).ifPresent(array -> {
final String values = Arrays.stream(array)
.filter(Objects::nonNull)
.map(Object::toString)
.collect(Collectors.joining("、"));
System.out.println("方法的参数列表为:" + values);
});
BiConsumer<Method, Object[]> before = (method, params) -> {
System.out.println(method.getName() + "方法执行之前被执行before方法");
consumer.accept(params);
};
BiConsumer<Method, Object[]> after = (method, params) -> {
System.out.println(method.getName() + "方法执行之后被执行after方法");
consumer.accept(params);
};
Target target = new DefaultTarget();
final Target proxy = (Target) JdkProxyUtils.getProxy(target, before, after);
proxy.doSomething();
}
}
最后,请大家点个赞吧…