【小工具】代理建造器 —— ProxyBuilder
需求分析:
在我们往常的编程中,有时会需要用到 代理机制
而代理机制 有两类:
- 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);
}
}