深入理解动态代理02

关于动态代理的内部原理请看前面的文章 深入理解动态代理。这次我们来谈谈动态代理的封装。

动态代理的封装

java通过Proxy.newProxyInstance()方法来动态获取我们需要的代理类字节文件,比如我们需要获取ArrayList的代理类,可以这么写:

List proxy = (List) Proxy.newProxyInstance(List.class.getClassLoader(), new Class[]{List.class}, new InvocationHandler(){
			List list = new ArrayList();
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				// TODO Auto-generated method stub
				return method.invoke(list, args);
			}
			
		});
		
proxy.add(111);

然后通过代理proxy来调用目标ArrayList的一些方法。
如果我们想在调用ArrayList的add()前后做一些动作,可以这么写:

List proxy = (List) Proxy.newProxyInstance(List.class.getClassLoader(), new Class[]{List.class}, new InvocationHandler(){
			List list = new ArrayList();
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				System.out.println("--调用add()之前--");
				Object obj = method.invoke(list, args);
				System.out.println("--调用add()之后--");
				// TODO Auto-generated method stub
				return obj;
			}
			
		});

写到这里,我们想到一个问题,如何动态地将新添加的代码添加到指定的位置?也是就如何将我们新加入的两句 System.out.print语句动态添加到代理方法中?

这里有一个方法,就是把我们需要修改的操作封装到一个类的方法中,然后把这个类传给代理,这样代理就可以通过这个类来操作其方法了。具体代码如下:

1.首先创建一个修改操作接口

public interface Advice {
	void before();
	void after();
}

2.创建具体修改操作目标封装类

public class MyAdvice implements Advice{

	@Override
	public void before() {
		// TODO Auto-generated method stub
		System.out.println("--目标方法调用之前--");
	}

	@Override
	public void after() {
		// TODO Auto-generated method stub
		System.out.println("--目标方法调用之后--");
	}

}

3.封装代理方法:

private static Object getProxy(final Object target, final Advice advice){
		//动态获取target的代理类
		Object proxy = (Object) Proxy.newProxyInstance(
				target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), 
				new InvocationHandler(){

					@Override
					public Object invoke(Object proxy, Method method,
							Object[] args) throws Throwable {
						// TODO Auto-generated method stub
						advice.before();
						Object obj = method.invoke(target, args);
						advice.after();
						return obj;
					}
					
				});
		return proxy;
	}

至此,代理获取的封装方法完成了,现在如果我们想在Arraylist调用add()前后插入我们的修改动作只需这么做:

List target = new ArrayList();
List proxy1 = (List) getProxy(target,new MyAdvice());
proxy1.add(111);

其实,这与AOP编程的思想如出一辙,我们也可以用这种方式简单实现AOP。

你可能感兴趣的:(Java)