[关闭]
@Yano 2016-07-26T15:33:12.000000Z 字数 4216 阅读 2023

Java Proxy pattern

Java


什么是代理?

proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. In short, a proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes.

Use of the proxy can simply be forwarding to the real object, or can provide additional logic. In the proxy extra functionality can be provided, for example caching when operations on the real object are resource intensive, or checking preconditions before operations on the real object are invoked. For the client, usage of a proxy object is similar to using the real object, because both implement the same interface.

Proxy pattern 是一种设计模式。

从广义上来说,代理是某个对象的接口的实现。代理可以是任意接口的实现:一个网络连接,一个内存中大的对象,一个文件,或者是其他很难或者不能复制的资源。简而言之,客户端能够通过代理,访问真实的对象,也可以增加额外的逻辑。对于客户端而言,使用代理和使用真实的对象是一样的,因为两者都实现了相同的接口。

Example 静态代理

Image

  1. public interface Image {
  2. public void displayImage();
  3. }

RealImage

  1. public class RealImage implements Image {
  2. private String filename;
  3. public RealImage(String filename) {
  4. this.filename = filename;
  5. loadImageFromDisk();
  6. }
  7. private void loadImageFromDisk() {
  8. System.out.println("Loading " + filename);
  9. }
  10. public void displayImage() {
  11. System.out.println("Displaying " + filename);
  12. }
  13. }

ProxyImage

  1. public class ProxyImage implements Image{
  2. private String filename;
  3. private Image image;
  4. public ProxyImage(String filename){
  5. this.filename=filename;
  6. }
  7. public void displayImage() {
  8. if (image==null) {
  9. image=new RealImage(filename);
  10. }
  11. image.displayImage();
  12. }
  13. }

Test

  1. public class Test {
  2. public static void main(String[] args) {
  3. Image image1 = new ProxyImage("image1");
  4. image1.displayImage();
  5. Image image2 = new ProxyImage("image2");
  6. image2.displayImage();
  7. }
  8. }

输出

  1. Loading image1
  2. Displaying image1
  3. Loading image2
  4. Displaying image2

Example 动态代理

java.lang.reflect.InvocationHandler

InvocationHandler is the interface implemented by the invocation handler of a proxy instance.

Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.

java.lang.reflect.Proxy

Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods.

To create a proxy for some interface Foo:

  1. InvocationHandler handler = new MyInvocationHandler(...);
  2. Class<?> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
  3. Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);

or more simply:

  1. Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class<?>[] { Foo.class }, handler);

A dynamic proxy class (simply referred to as a proxy class below) is a class that implements a list of interfaces specified at runtime when the class is created, with behavior as described below. A proxy interface is such an interface that is implemented by a proxy class. A proxy instance is an instance of a proxy class. Each proxy instance has an associated invocation handler object, which implements the interface InvocationHandler. A method invocation on a proxy instance through one of its proxy interfaces will be dispatched to the invoke method of the instance's invocation handler, passing the proxy instance, a java.lang.reflect.Method object identifying the method that was invoked, and an array of type Object containing the arguments. The invocation handler processes the encoded method invocation as appropriate and the result that it returns will be returned as the result of the method invocation on the proxy instance.

Demo

BookInterface接口,定义抽象方法addBook()。

  1. public interface BookInterface {
  2. public void addBook();
  3. }

BookImpl类,实现了接口的addBook()方法。

  1. public class BookImpl implements BookInterface {
  2. public void addBook() {
  3. System.out.println("addBook method");
  4. }
  5. }

BookProxy类实现了InvocationHandler接口。

  1. /**
  2. * JDK动态代理类
  3. *
  4. * @author Administrator
  5. *
  6. */
  7. public class BookProxy implements InvocationHandler {
  8. private Object target;
  9. /**
  10. * 绑定委托对象,并返回一个代理类
  11. * @param target
  12. * @return
  13. */
  14. public Object bind(Object target) {
  15. this.target = target;
  16. //取得代理对象,但是要绑定接口
  17. return Proxy.newProxyInstance(target.getClass().getClassLoader(),
  18. target.getClass().getInterfaces(), this);
  19. }
  20. /**
  21. * 调用方法
  22. */
  23. public Object invoke(Object proxy, Method method, Object[] args)
  24. throws Throwable {
  25. Object result = null;
  26. result = method.invoke(target, args);
  27. return result;
  28. }
  29. }

TestProxy

  1. public class TestProxy {
  2. public static void main(String[] args) {
  3. // 生成一个动态代理类 proxy
  4. BookProxy proxy = new BookProxy();
  5. // 绑定接口,并返回动态代理 bookProxy
  6. BookInterface bookProxy = (BookInterface) proxy.bind(new BookImpl());
  7. bookProxy.addBook();
  8. }
  9. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注