自J2SE 1.3以后,加入了java.lang.reflect.Proxy类,可协助实现动态代理类功能。本例假设打算开发一个HelloSpeaker类,其中有一个hello()方法,想要在这个hello()调用前后加上记录的功能,但又不想将记录的功能加入到HelloSpeaker类中,此时可以使用Proxy类来实现动态代理。实际上,这个跟Spring中面向切面编程AOP几乎一样。
第一步,创建IHello.java接口
package com.xiaofan.demo.proxy; public interface IHello { public void hello(String name); }
第二步,创建HelloSpeaker.java实现
package com.xiaofan.demo.proxy; public class HelloSpeaker implements IHello { public void hello(String name) { System.out.println("Hello, " + name); } }
第三步,创建代理LogHandler.java
package com.xiaofan.demo.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.logging.Level; import java.util.logging.Logger; public class LogHandler implements InvocationHandler { private Logger logger = Logger.getLogger( this.getClass().getName()); private Object delegate ; public Object bind( Object delegate ){ this.delegate = delegate; return Proxy.newProxyInstance( delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(), this ); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try{ logger.log( Level.INFO, "method starts ... " + method.getName() ); result =method.invoke( delegate, args ); logger.log(Level.INFO, "method ends ... " + method.getName() ); } catch( Exception e ){ logger.log( Level.INFO, e.toString() ); } return result ; } }
第四步,创建应用实例 ProxyDemo.java
package com.xiaofan.demo.proxy; public class ProxyDemo { public static void main(String[] args) { LogHandler handler = new LogHandler(); IHello speaker = new HelloSpeaker(); IHello speakerProxy = (IHello)handler.bind( speaker ); speakerProxy.hello( "xiaofan" ); } }
至此,Proxy实例完成。总结一下,要能使用Proxy,需要被代理对象实现了接口。然后通过接口来完成方法的调用。这是使用Proxy来创建代理的一般约定,当然如果要自己写实现,那是否实现接口等都不是问题了。