当前位置:首页 > 开发 > 编程语言 > Java > 正文

Java Dynamic Proxy

发表于: 2015-01-06   作者:DavyJones2010   来源:转载   浏览次数:
摘要: 1) Act as a simple log interceptor: public class DynamicProxy { private static final Logger logger = Logger.getLogger(DynamicProxy.class); @SuppressWarnings("unchecked") @Test publi

1) Act as a simple log interceptor:

public class DynamicProxy {
	private static final Logger logger = Logger.getLogger(DynamicProxy.class);
	@SuppressWarnings("unchecked")
	@Test
	public void useProxyTest() {
		String str = "Hello world";
		LoggingInvocationHandler handler = new LoggingInvocationHandler(str);
		Comparable<String> obj = (Comparable<String>) Proxy.newProxyInstance(
				this.getClass().getClassLoader(),
				new Class[]{Comparable.class}, handler);
		obj.compareTo("Yes");
	}
	public static class LoggingInvocationHandler implements InvocationHandler {
		private Object targetObject;

		public LoggingInvocationHandler(Object targetObject) {
			this.targetObject = targetObject;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			logger.info(String.format("Invoking method: [%s], args: [%s]",
					method.getName(), Lists.newArrayList(args)));

			return method.invoke(targetObject, args);
		}
	}
}

 

2) Act as a simple adapter between two different interfaces:

public class DynamicProxy {
	private static final Logger logger = Logger.getLogger(DynamicProxy.class);
	public static interface GreetV1 {
		String greet(String name, String gender) throws IOException;
	}
	public static interface GreetV2 {
		String greet(String username);
	}
	public class GreetAdapter implements InvocationHandler {
		private GreetV1 greetInstance;

		public GreetAdapter(GreetV1 greetInstance) {
			super();
			this.greetInstance = greetInstance;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			String methodName = method.getName();
			if ("greet".equals(methodName)) {
				String username = (String) args[0];
				String name = lookupName(username);
				String gender = lookupGender(username);
				logger.info(proxy.getClass());
				// ((GreetV2)proxy).greet(username);
				try {
					return greetInstance.greet(name, gender);
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			} else {
				return method.invoke(greetInstance, args);
			}
		}
		private String lookupGender(String username) {
			// Dummy
			return "Male";
		}

		private String lookupName(String username) {
			// Dummy
			return "Yang";
		}
	}
	@Test
	public void adapterTest() {
		GreetAdapter adapter = new GreetAdapter(new GreetV1() {
			@Override
			public String greet(String name, String gender) throws IOException {
				return String.format("Hello %s[%s]", name, gender);
			}
		});
		GreetV2 greetV2 = (GreetV2) Proxy.newProxyInstance(this.getClass()
				.getClassLoader(), new Class[]{GreetV2.class}, adapter);
		assertEquals("Hello Yang[Male]", greetV2.greet("Yang, Kunlun"));
		logger.info(greetV2.getClass());
	}
}

   The first argument "proxy" in method invoke()  is actually the "greetV2" instance.   

   greetV2 is indeed an instance of an anonymous class who extends java.lang.reflect.Proxy and implements GreetV2 interface.

   And it has an InvocationHandler property which points to  "adapter".

   If we decomment the "((GreetV2)proxy).greet(username)", the "java.lang.StackOverflowError" will occur.

   See simplified Proxy code below:

public class Proxy implements java.io.Serializable {
    protected InvocationHandler h;
    protected Proxy(InvocationHandler h) {
        this.h = h; // As the dynamically generated class extends Proxy, therefore it has this InvocationHandler property.
    }
   public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
    {
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            return newInstance(cons, ih); // creates a new instance that extends java.lang.reflect.Proxy and implements the interfaces passed in.
    }
}

Reference Links:

http://guojuanjun.blog.51cto.com/277646/1221281

http://paddy-w.iteye.com/blog/841798

Java Dynamic Proxy

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
从JDK1.3开始,Java就引入了动态代理的概念。动态代理(Dynamic Proxy)可以帮助你减少代码行数,真
从JDK1.3开始,Java就引入了动态代理的概念。动态代理(Dynamic Proxy)可以帮助你减少代码行数,真
什么是动态代理? 被代理的对象(真实主题(RealSubject))可以在运行时动态改变,需要控制的接口(
从JDK1.3开始,Java就引入了动态代理的概念。动态代理(Dynamic Proxy)可以帮助你减少代码行数,真
暂且先将AOP这个英文缩写名词放到一边,先从一个简单常见的例子来着手,这个例子当中含有日志(Logg
原写于2010-12-12 一.摘要 1.什么是“代理” 2.代理模式与适配器模式、装饰者模式的区别,适用场景
Overview Usually, the proxy class is already available as Java bytecodes, having been compile
前言 我们常用的一些proxy的手法或者设计模式都是本质上通过一个中间的代理类来引用实际的功能实现
一篇杂文,写到哪就说到哪。在一些框架中有所谓的截面(aop),这些应用主要就是使用了JAVA的动态代理
1. 创建一个web工程,此处用eclipse创建(如果对创建web工程很熟悉,可以不看的,本文目的是做一个
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号