通过以下几种方式介绍动态代理
- 动态代理涉及到的类
- 动态代理用法
- Proxy类解析
- 动态代理类解析
动态代理涉及到的类
InvocationHandler(Interface)// 处理类
//参数-> 代理类对象,被代理类的方法,被代理类方法参数(MyInvocationHandler 类中有印证)
//返回值-> 被代理类方法返回结果
public Object invoke(Object proxy, Method method, Object[] args)
Proxy(Class)// 动态创建一个代理对象的类
// 参数->类加载器,被代理类实现的接口,InvocationHandler 实现类
// 返回值->代理类(动态生成)
public static Object newProxyInstance(ClassLoader loader,Class>[] interfaces,InvocationHandler h)
// 参数->类加载器,被代理类实现的接口
// 返回值->未被实例化的代理类(构造器参数类型为InvocationHandler)
public static Class> getProxyClass(ClassLoader loader,Class>... interfaces)
动态代理用法
public class Test {
public static void main(String[] args) throws Exception{
proxyTest1();// 方法一
proxyTest2();// 方法二
}
// 动态代理方法一
private static void proxyTest1() {
// 创建订单方法
OrderInterface order = new OrderService();
InvocationHandler invocationHandler = getInvocationHandler(order);
/**
* Proxy.newProxyInstance 方法三个参数
* ClassLoader loader 类加载器
* Class>[] interfaces 订单类接口
* InvocationHandler h 处理器(内含增强方法-打印处理订单日志)
*
* 通过类加载器和订单类接口动态创建代理类,
* 然后将处理器设置进动态代理类,
* 返回实现订单类接口的动态代理实现类(动态生成)
*
* */
OrderInterface orderInterface = (OrderInterface)Proxy.newProxyInstance(order.getClass().getClassLoader(), order.getClass().getInterfaces(), invocationHandler);
orderInterface.createOrder(new OrderInfo());
}
// 动态代理方法二
private static void proxyTest2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 创建订单方法
OrderInterface order = new OrderService();
InvocationHandler invocationHandler = getInvocationHandler(order);
/**
* ClassLoader loader 类加载器
* Class>... interfaces 订单类接口
*
* 通过类加载器和订单类接口动态创建代理类
* */
Class> clazz = Proxy.getProxyClass(order.getClass().getClassLoader(), order.getClass().getInterfaces());
/**
* 获取参数为InvocationHandler类型的构造器
* */
Constructor constructor = clazz.getConstructor(InvocationHandler.class);
/**
* 将处理器传进参数里,实例化类,进行调用以达到增强方法的目的
* */
OrderInterface orderInterface = (OrderInterface)constructor.newInstance(invocationHandler);
orderInterface.createOrder(new OrderInfo());
}
// InvocationHandler 处理器
private static InvocationHandler getInvocationHandler(OrderInterface order) {
// 内部实现InvocationHandler接口,增强被代理类方法功能
InvocationHandler invocationHandler = new MyInvocationHandler(order);
return invocationHandler;
}
}
处理类
public class MyInvocationHandler implements InvocationHandler {
private Object object;
public MyInvocationHandler(Object object) {
this.object = object;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(new StringBuilder("Object proxy-->className:").append(proxy.getClass().getName()));
System.out.println(new StringBuilder("Method method-->methodName:").append(method.getName()));
if (null != args && args.length > 0) {
System.out.println(new StringBuilder("Object[] args-->paramValue:").append(args[0].toString()));
}
System.out.println(new StringBuilder("增强方法:").append("记录日志...").toString());
Object returnObject = method.invoke(object, args);
return returnObject;
}
}
订单类接口
public interface OrderInterface {
public void createOrder(OrderInfo order);
}
订单处理类(执行下单流程)
public class OrderService implements OrderInterface {
public void createOrder(OrderInfo order) {
System.out.print("创建订单");
try {
for (int i = 0; i < 3; i++) {
Thread.sleep(500);
System.out.print(".");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("");
System.out.println("订单创建成功");
}
}
实体类
public class OrderInfo {
@Override
public String toString() {
return "ClassName-->OrderInfo";
}
}
Proxy类解析
属性及构造器
// 构造器参数类型
private static final Class>[] constructorParams = { InvocationHandler.class };
// 代理类缓存,采用弱引用方式进行缓存,方便jvm进行gc垃圾回收
private static final WeakCache[], Class>> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
// 处理类,通过构造器进行赋值。1:子类继承Proxy类,构造器赋值,2:Proxy.newProxyInstance()调用该方法生成代理类,利用反射创建代理类进行构造器赋值
protected InvocationHandler h;
// 提供的两种构造器限制了我们使用Proxy类只能直接调用静态方法
private Proxy() {
}
// 创建动态代理类会使用到该构造器
protected Proxy(InvocationHandler h) {
this.h = h;
}
方法
// 获取代理类(在文章开头有介绍此方法)。
public static Class> getProxyClass(ClassLoader loader, Class>... interfaces) throws IllegalArgumentException
{
final Class>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
// 获取代理类
return getProxyClass0(loader, intfs);
}
// 获取代理类,并且生成代理类实例(在文章开头有介绍此方法)。
public static Object newProxyInstance(ClassLoader loader, Class>[] interfaces, InvocationHandler h) throws IllegalArgumentException
{
// 代码和getProxyClass方法目的一致,获取动态代理类。
-------------------------------------------------------------------------
Objects.requireNonNull(h);
final Class>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
Class> cl = getProxyClass0(loader, intfs);
-------------------------------------------------------------------------
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
// 通过反射获取参数为InvocationHandler类型的构造器
final Constructor> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
// 实例化动态代理类,并指定构造器参数
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
// 生成动态代理类
private static Class> getProxyClass0(ClassLoader loader, Class>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// 代理类的获取及创建(使用了弱引用方式)
return proxyClassCache.get(loader, interfaces);
}
动态代理类解析(生成代理类方法在git中)
// ProxyObject 随意指定的一个类名,该类继承了Proxy(构造赋值),实现了OrderInterface接口(实现代理方法)
public final class ProxyObject extends Proxy implements
{
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
// 代理类构造,参数为InvocationHandler 类型。上文介绍了,Proxy 类InvocationHandler 赋值第一种方式:子类继承Proxy类,构造器赋值
public ProxyObject(InvocationHandler paramInvocationHandler)
{
super(paramInvocationHandler);
}
static
{
try
{
// 反射生成方法内所有方法的Method对象
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m3 = Class.forName("proxy.OrderInterface").getMethod("createOrder", new Class[] { Class.forName("proxy.OrderInfo") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
// 创建订单方法(代理方法)
public final void createOrder(OrderInfo paramOrderInfo)
{
try
{
// 执行InvocationHandler实现类的invoke方法(方法参数在文章开头有介绍)。
this.h.invoke(this, m3, new Object[] { paramOrderInfo });
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final boolean equals(Object paramObject)
{
try
{
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final String toString()
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
//hashCode() 略
}
代码地址:https://gitee.com/chenxu_jdk/proxy-test