代理是设计模式的一种,代理类为委托类提供消息预处理,消息转发,事后消息处理等功能。Java中的代理分为三种角色:
三者关系可以表示如下图:
Java中的代理按照代理类生成时机不同又分为静态代理和动态代理。静态代理代理类在编译期就生成,而动态代理代理类则是在Java运行时动态生成。
Java中的静态代理要求代理类(ProxySubject)和委托类(RealSubject)都实现同一个接口(Subject)。静态代理中代理类在编译期就已经确定,而动态代理则是JVM运行时动态生成,静态代理的效率相对动态代理来说相对高一些,但是静态代理代码冗余大,一单需要修改接口,代理类和委托类都需要修改。 举个例子:
interface HelloService { void sayHello(); } 复制代码
class HelloServiceImpl implements HelloService { @Override public void sayHello() { System.out.println("Hello World!"); } } 复制代码
class HelloServiceProxy implements HelloService { private HelloService helloService; public HelloServiceProxy(HelloService helloService) { this.helloService = helloService; } @Override public void sayHello() { System.out.println("Before say hello..."); helloService.sayHello(); System.out.println("After say hello..."); } } 复制代码
public class HelloServiceProxyTest { public static void main(String[] args) { HelloService helloService = new HelloServiceImpl(); HelloServiceProxy proxy = new HelloServiceProxy(helloService); proxy.sayHello(); } } 复制代码
Before say hello... Hello World! After say hello... 复制代码
Java中的动态代理依靠反射来实现,代理类和委托类不需要实现同一个接口。委托类需要实现接口,否则无法创建动态代理。代理类在JVM运行时动态生成,而不是编译期就能确定。 Java动态代理主要涉及到两个类: java.lang.reflect.Proxy
和 java.lang.reflect.InvocationHandler
。代理类需要实现InvocationHandler接口或者创建匿名内部类,而Proxy用于创建动态动态。 我们用动态代理来实现HelloService:
interface HelloService { void sayHello(); } 复制代码
class HelloServiceImpl implements HelloService { @Override public void sayHello() { System.out.println("Hello World!"); } } 复制代码
class HelloServiceDynamicProxy { private HelloService helloService; public HelloServiceDynamicProxy(HelloService helloService) { this.helloService = helloService; } public Object getProxyInstance() { return Proxy.newProxyInstance(helloService.getClass().getClassLoader(), helloService.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before say hello..."); Object ret = method.invoke(helloService, args); System.out.println("After say hello..."); return ret; } }); } } 复制代码
public class HelloServieDynamicProxyTest { public static void main(String[] args){ HelloService helloService = new HelloServiceImpl(); HelloService dynamicProxy = (HelloService) new HelloServiceDynamicProxy(helloService).getProxyInstance(); dynamicProxy.sayHello(); } } 复制代码
Before say hello... Hello World! After say hello... 复制代码