java 动态代理类的实现,原理及应用
在目前的Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。
其实现主要通过是java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。
Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现,如下,HelloWorld接口定义的业务方法,HelloWorldImpl是HelloWorld接口的实现,HelloWorldHandler是InvocationHandler接口实现。代码如下:
业务接口:
public interface HelloWorld { void sayHelloWorld() ;}public class HelloWorldImpl implements HelloWorld { public void sayHelloWorld() { System.out.println("Hello World!"); }}import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class HelloWorldHandler implements InvocationHandler { //要代理的原始对象 private Object objOriginal; /** * 构造函数。 * @param obj 要代理的原始对象。 */ public HelloWorldHandler(Object obj) { this.objOriginal = obj ; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result ; //方法调用之前 doBefore(); //调用原始对象的方法 result = method.invoke(this.objOriginal ,args); //方法调用之后 doAfter(); return result ; } private void doBefore() { System.out.println("before method invoke!"); } private void doAfter() { System.out.println("after method invoke!"); }}import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { HelloWorld hw = new HelloWorldImpl(); InvocationHandler handler = new HelloWorldHandler(hw); HelloWorld proxy = (HelloWorld) Proxy.newProxyInstance( hw.getClass().getClassLoader(), hw.getClass().getInterfaces(), handler); proxy.sayHelloWorld(); }}before method invoke!Hello World!after method invoke!
public static Class getProxyClass(ClassLoader loader, Class[] interfaces) throws IllegalArgumentException
public static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler handler)throws IllegalArgumentException
View Code/**** 方式一 ****///创建InvocationHandler对象InvocationHandler handler = new MyInvocationHandler(...);//创建动态代理类Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[] { Foo.class });//创建动态代理类的实例Foo foo = (Foo) proxyClass.getConstructor( new Class[] { InvocationHandler.class}).newInstance(new Object[] { handler });/**** 方式二 ****///创建InvocationHandler对象InvocationHandler handler = new MyInvocationHandler(...);//直接创建动态代理类的实例Foo foo = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class },handler);package proxy;import java.lang.reflect.*;public class HelloServiceProxyFactory {/** 创建一个实现了HelloService接口的动态代理类的实例* 参数helloService引用被代理的HelloService实例*/public static HelloService getHelloServiceProxy(final HelloService helloService){//创建一个实现了InvocationHandler接口的匿名类的实例InvocationHandler handler=new InvocationHandler(){public Object invoke(Object proxy,Method method,Object args[])throws Exception{System.out.println("before calling "+method); //预处理Object result=method.invoke(helloService,args);//调用被代理的HelloService实例的方法System.out.println("after calling "+method); //事后处理return result;}};Class classType=HelloService.class;return (HelloService)Proxy.newProxyInstance(classType.getClassLoader(),new Class[]{classType},handler);}//# getHelloServiceProxy()}package proxy;public class Client2{public static void main(String args[]){HelloService helloService=new HelloServiceImpl();HelloService helloServiceProxy=HelloServiceProxyFactory.getHelloServiceProxy(helloService);System.out.println("动态代理类的名字为"+helloServiceProxy.getClass().getName());System.out.println(helloServiceProxy.echo("Hello"));}}打印结果如下:动态代理类的名字为$Proxy0before calling public abstract java.lang.String proxy.HelloService.echo(java.lang.String)after calling public abstract java.lang.String proxy.HelloService.echo(java.lang.String)echo:Hello