Java中从1.3中引入Proxy,实现接口的动态代理。JDK的动态代理,就是在程序运行的过程中,根据被代理的接口来动态生成代理类的class文件,并加载运行的过程。本文从简单例子入手,通过分析源码看看其内部实现原理,使用的是JDK 1.8。
简单运用
使用动态代理主要涉及接口InvocationHandler,以及Proxy类。
通过动态代理实现对接口中方法调用前后进行拦截处理
创建要代理的接口,以及一个实现类。
package com.proxy;
/**
*
* 要代理的接口<br/>
*
* @version
*/
public interface PeopleService {
public void sayHello();
public void printName(String name);
}
简单实现类EnglishService
package com.proxy;
/**
*
* 注释内容<br/>
*
*
* @version
*/
public class EnglishService implements PeopleService {
@Override
public void sayHello() {
System.out.println("Hi~");
}
@Override
public void printName(String name) {
System.err.println("Your name:" + name);
}
}
定义自己的InvocationHandler
package com.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*
* 注释内容<br/>
*
* @version
*/
public class MyInvocationHandler implements InvocationHandler {
//目标对象
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//调用前打印
System.err.println("------begin----------");
method.invoke(target, args);
System.err.println("------end----------");
return null;
}
}
编写测试类
package com.test;
import java.lang.reflect.Proxy;
import org.testng.annotations.Test;
import com.proxy.EnglishService;
import com.proxy.MyInvocationHandler;
import com.proxy.PeopleService;
public class MyTest {
@Test
public void proxyTest() {
MyInvocationHandler handler = new MyInvocationHandler(new EnglishService());
PeopleService proxyService = (PeopleService) Proxy.newProxyInstance(MyTest.class.getClassLoader(), new Class[] { PeopleService.class }, handler);
proxyService.sayHello();
}
}
运行结果:
成功实现对接口方法的前后拦截。JDK内部究竟怎么实现代理的?什么时候调用MyInvocationHandler 的invoke方法?下面分析原理:
看代理类获取时,关键代码为Proxy.newProxyInstance,源码:
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
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);
/*
* 通过传入的InvocationHander调用其构造器获取接口实例
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
//非公开接口的处理
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
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) {