JAVA实现动态代理常用的有两种方式:
1, java.lang.reflect.Proxy (JDK)
2, net.sf.cglib.proxy.Enhancer(cglib)
两者之间的区别如图1-1 所示。
图1-1 jdk 和 cglib 概要图
jdk和cglib实现动态代理的原理是完全不同的,jdk是通过目标class所实现的接口,而cglib是通过目标对象的子类完成的。
他们二者互相补充,基本上能够满足所有的动态代理需求。
jdk和cglib实现动态代理的简单例子如下所示:
jdk:
****************************************************************************************************
1,定义接口
public interface SubInter {
public abstract void display() ;
public abstract void display2();
}
2, 定义实现类
public class SonObject implements SubInter {
@Override
public void display() {
System.out.println("This is a realy object !");
}
@Override
public void display2() {
System.out.println("This is a test2!");
}
}
3, 设置回调类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class Dynamic implements InvocationHandler {
private Object object;
private String validateString;
public Dynamic(Object object, String validateString) {
this.object = object;
this.validateString = validateString;
}
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
boolean b = validateMehod(arg1.getName());
Object object = null;
if (b) {
before();
object = arg1.invoke(this.object, arg2);
after();
}else {
object = arg1.invoke(this.object, arg2);
}
return object;
}
public boolean validateMehod(String methodName) {
boolean b = false;
String methodNames[] = validateString.split("&");
for (String name : methodNames) {
if (methodName.contains(name)) {
b = true;
return b;
}
}
return b;
}
public void before() {
System.out.println("Before");
}
public void after() {
System.out.println("after");
}
}
4, 动态代理工厂
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
*
* @author gyf
*
* We can get a proxy instance for the target object by the specify
* InvocationHandler.
*
*/
public class DynamicProxyFactory {
public static Object createProxyInstance(Object targetObject,
InvocationHandler handler) {
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), handler);
}
}
5, 单元测试
public class Junit {
@Test
public void testJDK() {
SubInter targetObject = new SonObject();
InvocationHandler handler = new Dynamic(targetObject, "2&3");
SubInter object = (SubInter)DynamicProxyFactory.createProxyInstance(targetObject, handler);
object.display2();
}
}
cglib
*************************************************************************************************
1, 定义目标类
public class TargetObject {
public void display() {
System.out.println("This is a test");
}
public void display2() {
System.out.println("This is a test2");
}
}
2, 定义回调类
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibDynamic implements MethodInterceptor{
private Object targetObject;
public CglibDynamic(){}
public CglibDynamic(Object object) {
this.targetObject = object;
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
Object object = arg3.invoke(targetObject, arg2);
return object;
}
}
3, 定义动态代理工厂
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
public class CglibDynamicFactory {
public static Object getProxyInstance(Object targetObject,
MethodInterceptor methodInterceptor) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetObject.getClass());
enhancer.setCallback(methodInterceptor);
return enhancer.create();
}
}
4, 单元测试
import net.sf.cglib.proxy.MethodInterceptor;
import org.junit.Test;
import com.cglib.proxy.CglibDynamic;
import com.cglib.proxy.CglibDynamicFactory;
import com.cglib.proxy.TargetObject;
public class Junit {
@Test
public void testCglib() {
TargetObject object = new TargetObject();
MethodInterceptor interceptor = new CglibDynamic(object);
TargetObject son = (TargetObject)CglibDynamicFactory.getProxyInstance(object, interceptor);
son.display();
}
}
当然Hibernate现在采用了javasist来取代cglib, 有关javasist我会继续学习。