【小工具】代理建造器 —— ProxyBuilder

YouzgLogo

需求分析:

在我们往常的编程中,有时会需要用到 代理机制
而代理机制 有两类:

  • JDK提供的 Proxy代理模式
  • cglib-nodep.jar提供的 CGLib代理模式

有时候,我们可能在一个项目中,因为项目需求,而用到两种代理模式
这时候,我们要进行许多重复的代码

因此,在本篇博文中,本人将提供一个小工具,以便我们快速获得 所需的代理对象:


首先,本人来声明下所需的 Jar包支持

Jar包支持:

  • cglib-nodep

实现过程:

首先,本人给出一个IMethdInvoker接口
来封装通过反射机制调用被代理方法的步骤:

IMethdInvoker接口:

package edu.youzg.util.proxy;

import java.lang.reflect.Method;

/**
 * 设置 “拦截逻辑”
 *
 * @author Youzg
 */
public interface IMethodInvoker {
    /**
     * 代理对象 调用方法
     *
     * @param object 代理对象
     * @param method 要加强的 调用的方法
     * @param args   传递的参数
     * @return 调用结果
     */
    <T> T methodInvoke(Object object, Method method, Object[] args);
}

现在,本人来给出 本篇博文的核心类 —— ProxyBuilder类

ProxyBuilder类:

package edu.youzg.util.proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理对象 建造者
 */
public class ProxyBuilder {
	public static final int JDK_PROXY = 0;
	public static final int CGLIB_PROXY = 1;

	private IMethodInvoker methodInvoker;
	private int proxyType = JDK_PROXY;

	public ProxyBuilder() {
	}

	public ProxyBuilder(int proxyType) {
		if (proxyType != CGLIB_PROXY) {	// 防止 使用者胡乱使用
			proxyType = JDK_PROXY;
		}
		this.proxyType = proxyType;
	}

	public void setMethodInvoker(IMethodInvoker methodInvoker) {
		this.methodInvoker = methodInvoker;
	}

	public void setProxyType(int proxyType) {
		this.proxyType = proxyType;
	}

	public <T> T creatProxy(T object) {
		return creatProxy(object.getClass());
	}

	@SuppressWarnings("unchecked")
	public <T> T creatProxy(Class<?> klass) {
		if (klass.isInterface()) {
			return creatJdkProxy(klass, null);
		}

		if (this.proxyType == JDK_PROXY) {
			try {
				Object target = klass.newInstance();
				return (T) creatJdkProxy(klass, target);
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}

		return creatCglibProxy(klass);
	}

	/**
	 * 获取cglib代理对象
 	 */
	@SuppressWarnings("unchecked")
	private <T> T creatCglibProxy(Class<?> klass) {
		try {
			T target = (T) klass.newInstance();
			Enhancer enhancer = new Enhancer();
			enhancer.setSuperclass(target.getClass());

			enhancer.setCallback(new MethodInterceptor() {

				@Override
				public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
					return invokeMethod(method, target, args);
				}
			});

			return (T) enhancer.create();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取jdk代理对象
	 * @param klass 目标对象 对应的 Class对象
	 * @param target 目标对象
	 * @param <T> 目标对象的类型
	 * @return 目标对象的 jdk代理对象
	 */
	@SuppressWarnings("unchecked")
	private <T> T creatJdkProxy(Class<?> klass, T target) {
		ClassLoader classLoader = klass.getClassLoader();
		Class<?>[] interfaces = klass.getInterfaces();
		if (klass.isInterface()) {
			interfaces = new Class<?>[]{klass};
		}
		Object proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				return invokeMethod(method, target, args);
			}
		});

		return (T) proxy;
	}

	/**
	 * 执行 被代理对象 的原方法
	 * @param method 被代理对象 的原方法
	 * @param target 被代理的 对象
	 * @param args 被代理对象 执行原方法 的参数
	 * @return 被代理对象 的原方法 的执行结果
	 * @throws Throwable
	 */
	private Object invokeMethod(Method method, Object target, Object[] args) throws Exception {
		if (methodInvoker == null) {
			return method.invoke(target, args);
		}
		return methodInvoker.methodInvoke(target, method, args);
	}
	
}

那么,现在本人来给出一个测试类,来看看我们设计的 ProxyBuilder小工具 是否成功:

小测试:

首先是一个测试接口:

ISimpleInterface接口:

package edu.youzg.test;

/**
 * 测试接口
 */
public interface ISimpleInterface {
    void hello(String master);
}

接下来 是这个接口的实现类

SimpleClass类:

package edu.youzg.test;

/**
 * 测试接口的 实现子类
 */
public class SimpleClass implements ISimpleInterface {

    @Override
    public void hello(String master) {
        System.out.println("hello " + master);
    }

}

最后,本人来给出一个测试类:

测试主类:

package edu.youzg.test;

import edu.youzg.util.proxy.IMethodInvoker;
import edu.youzg.util.proxy.ProxyBuilder;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Demo {

    public static void main(String[] args){
        ProxyBuilder proxyBuilder = new ProxyBuilder();
        proxyBuilder.setProxyType(ProxyBuilder.JDK_PROXY);

        ISimpleInterface aClass = new SimpleClass();
        proxyBuilder.setMethodInvoker(new IMethodInvoker() {
            @Override
            public Object methodInvoke(Object object, Method method, Object[] args) {
                try {
                    System.out.println("该方法被前置拦截... ...");
                    method.invoke(object, args);
                    System.out.println("该方法被后置拦截... ...");
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                return object;  // 返回的是 原执行对象
            }
        });
        ISimpleInterface proxy = proxyBuilder.creatProxy(aClass);
        proxy.hello("youzg");
    }

}

那么,现在本人来展示下运行结果:

运行结果:

运行结果 展示

那么,可以看到:
代理对象 获取 成功了!


完整代码:

IMethdInvoker接口:

package edu.youzg.util.proxy;

import java.lang.reflect.Method;

/**
 * 设置 “拦截逻辑”
 *
 * @author Youzg
 */
public interface IMethodInvoker {
    /**
     * 代理对象 调用方法
     *
     * @param object 代理对象
     * @param method 要加强的 调用的方法
     * @param args   传递的参数
     * @return 调用结果
     */
    <T> T methodInvoke(Object object, Method method, Object[] args);
}

ProxyBuilder类:

package edu.youzg.util.proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理对象 建造者
 * 
 * @author Youzg
 */
public class ProxyBuilder {
	public static final int JDK_PROXY = 0;
	public static final int CGLIB_PROXY = 1;

	private IMethodInvoker methodInvoker;
	private int proxyType = JDK_PROXY;

	public ProxyBuilder() {
	}

	public ProxyBuilder(int proxyType) {
		if (proxyType != CGLIB_PROXY) {	// 防止 使用者胡乱使用
			proxyType = JDK_PROXY;
		}
		this.proxyType = proxyType;
	}

	public void setMethodInvoker(IMethodInvoker methodInvoker) {
		this.methodInvoker = methodInvoker;
	}

	public void setProxyType(int proxyType) {
		this.proxyType = proxyType;
	}

	public <T> T creatProxy(T object) {
		return creatProxy(object.getClass());
	}

	@SuppressWarnings("unchecked")
	public <T> T creatProxy(Class<?> klass) {
		if (klass.isInterface()) {
			return creatJdkProxy(klass, null);
		}

		if (this.proxyType == JDK_PROXY) {
			try {
				Object target = klass.newInstance();
				return (T) creatJdkProxy(klass, target);
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}

		return creatCglibProxy(klass);
	}

	/**
	 * 获取cglib代理对象
 	 */
	@SuppressWarnings("unchecked")
	private <T> T creatCglibProxy(Class<?> klass) {
		try {
			T target = (T) klass.newInstance();
			Enhancer enhancer = new Enhancer();
			enhancer.setSuperclass(target.getClass());

			enhancer.setCallback(new MethodInterceptor() {

				@Override
				public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
					return invokeMethod(method, target, args);
				}
			});

			return (T) enhancer.create();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取jdk代理对象
	 * @param klass 目标对象 对应的 Class对象
	 * @param target 目标对象
	 * @param <T> 目标对象的类型
	 * @return 目标对象的 jdk代理对象
	 */
	@SuppressWarnings("unchecked")
	private <T> T creatJdkProxy(Class<?> klass, T target) {
		ClassLoader classLoader = klass.getClassLoader();
		Class<?>[] interfaces = klass.getInterfaces();
		if (klass.isInterface()) {
			interfaces = new Class<?>[]{klass};
		}
		Object proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				return invokeMethod(method, target, args);
			}
		});

		return (T) proxy;
	}

	/**
	 * 执行 被代理对象 的原方法
	 * @param method 被代理对象 的原方法
	 * @param target 被代理的 对象
	 * @param args 被代理对象 执行原方法 的参数
	 * @return 被代理对象 的原方法 的执行结果
	 * @throws Throwable
	 */
	private Object invokeMethod(Method method, Object target, Object[] args) throws Exception {
		if (methodInvoker == null) {
			return method.invoke(target, args);
		}
		return methodInvoker.methodInvoke(target, method, args);
	}
	
}

posted @ 2020-04-24 18:59  在下右转,有何贵干  阅读(306)  评论(0编辑  收藏  举报