目前,本人知道的动态代理实现方式有两种,一种是通过JDK自带的反射机制实现,另一种是第三方动态代理框架CGLIB。这两种方式,JDK实现的话获取代理对象会比CGLIB快,但是在使用代理对象,进行方法调用的时候,CGLIB却比JDK的快(性能高)!!
现在先介绍,JDK自带的反射机制包如何实现动态代理,本人已经写成通用的类
被代理类接口 ISayHello.java:
package dynamicproxy.jdk;
/**
* 文件名称: ISayHello.java
* 编写人: yh.zeng
* 编写时间: 17-1-18 下午6:14
* 文件描述: todo
*/
public interface ISayHello
{
public void sayHello();
}
两个被代理的类SayHelloImpl.java 和 SayHelloImpl2.java,这里写两个只是为了测试本人写的代理类实现是否是通用的
SayHelloImpl.java
package dynamicproxy.jdk;
/**
* 文件名称: SayHelloImpl.java
* 编写人: yh.zeng
* 编写时间: 17-1-18 下午6:15
* 文件描述: todo
*/
public class SayHelloImpl implements ISayHello
{
private String word = null;
@Override
public void sayHello() {
System.out.println("Hello World!");
}
}
SayHelloImpl2.java
package dynamicproxy.jdk;
/**
* 文件名称: SayHelloImp2.java
* 编写人: yh.zeng
* 编写时间: 17-1-18 下午7:19
* 文件描述: todo
*/
public class SayHelloImp2 implements ISayHello
{
private String word = null;
public SayHelloImp2(String word){
this.word = word;
}
@Override
public void sayHello() {
System.out.println(word);
}
}
动态代理实现类 JdkDynamicProxyHandler.java:
package dynamicproxy.jdk;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 文件名称: JdkDynamicProxyHandler.java
* 编写人: yh.zeng
* 编写时间: 17-1-18 下午6:25
* 文件描述: 动态代理工具类,通过JDK自带的反射机制包实现
*/
public class JdkDynamicProxyHandler implements InvocationHandler
{
private Object realObj = null; //被代理的对象,自动生成
private Class realClass = null; //被代理的类,作为参数传入构造方法
private Object[] realObjArgs = null; //被代理的类的构造方法的参数,作为参数传入构造方法
private Object proxyObj = null; //代理对象,自动生成
/**
*
* @param realClass 被代理的类
*/
public JdkDynamicProxyHandler(Class realClass){
this.realClass = realClass;
}
/**
*
* @param realClass 被代理的类
* @param args 被代理的类的构造方法的参数
*/
public JdkDynamicProxyHandler(Class realClass, Object... args){
this.realClass = realClass;
this.realObjArgs = args;
}
/**
* 获取代理对象
* @return Object
*/
public synchronized Object getProxyObj(){
if(proxyObj == null){
this.proxyObj = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), realClass.getInterfaces(), this);
}
return proxyObj;
}
/**
* 最终调用被代理的对象的方法的实现代码
* @param proxy
* @param method
* @param args
* @return 返回被代理对象调用相应方法返回的值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(realObj == null){
Constructor constructor = null;
if(realObjArgs != null && realObjArgs.length > 0){ //调用被代理类的有参构造方法进行实例化
Class clazz[] = new Class[realObjArgs.length];
for(int i = 0; i < clazz.length; i++){
clazz[i] = realObjArgs[i].getClass();
}
constructor = realClass.getConstructor(clazz);
realObj = constructor.newInstance(realObjArgs);
}else{ //调用被代理类的无参构造方法进行实例化
constructor = realClass.getConstructor();
realObj = constructor.newInstance();
}
}
return method.invoke(realObj, args);
}
}
测试demo:
package dynamicproxy.jdk;
import java.lang.reflect.Proxy;
/**
* 文件名称: JdkDynamicProxyTest.java
* 编写人: yh.zeng
* 编写时间: 17-1-18 下午6:24
* 文件描述: todo
*/
public class JdkDynamicProxyTest
{
public static void main(String args[]) {
//无构造参数demo
ISayHello sayHello = (ISayHello) new JdkDynamicProxyHandler(SayHelloImpl.class).getProxyObj();
sayHello.sayHello();
//有构造参数的demo
ISayHello sayHello2 = (ISayHello) new JdkDynamicProxyHandler(SayHelloImp2.class,new Object[]{"Hello World2!"}).getProxyObj();
sayHello2.sayHello();
}
}
Hello World!
Hello World2!
Process finished with exit code 0