`
learen
  • 浏览: 10671 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

黑马程序员 动态代理深入浅出

阅读更多

  ------- android培训java培训、期待与您交流! ----------

  假设我们现在有一个接口Hello里面有一个sayHello()的方法

public interface Hello {
	public void sayHello();
}

  和一个实现类HelloImpl

public class HelloImpl implements Hello {

	@Override
	public void sayHello() {
		System.out.println("Hello");
	}

}

   我们现在有这么一个需求,需要在sayHello()方法执行前做些事,在sayHello()方法执行后做些事,根据开放封闭原则不能改变原有的类,这该怎么办?

  这时就该轮到我们的动态代理出场了!

  首先介绍和动态代理有关的两个类:

  1.interface InvocationHandler

   只有一个Object invoke(Object proxy, Method method, Object[] args) 方法

   从参数列表可见这个类传入了需要代理的类的方法的方法对象method,通过这个对象可以调用需要代理的类的方法,args是这个方法的参数。也就是这个接口定义了一个统一的入口供Proxy代理类调用。通过我们对这个接口的不同实现来完成不同的附加功能,这就是多态的体现。

  2.class Proxy 
  真正表示动态代理的类,提供两个静态方法: 
  Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface)
  用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”,用来冒充真实的对象。从返回Class类型可见这个代理类是根据所传参数动态产生的,所以叫做动态代理。
  Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
  产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类),它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(...)方法,invoke方法就是我们用来做N多事情的地方\(^o^)/~。根据所传的InvocationHandler接口的实现产生动态代理类的实例。

  ---------------------------------可恶的分割线O(∩_∩)O~------------------------------------------------

  通过上面介绍,我们首先得生成一个InvocationHandler 接口的实现来完成我们的功能,并在bind()方法中返回根据这个实现了InvocationHandler 接口的对象所生成的动态代理类的实例

public class myHandler implements InvocationHandler {

	private Object target;

	/**
	 * 绑定委托对象并返回一个代理类
	 * 
	 * @param target
	 * @return
	 */
	public Object bind(Object target) {
		this.target = target;
		// 取得代理对象
		return Proxy.newProxyInstance(target.getClass().getClassLoader(),
				target.getClass().getInterfaces(), this);
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result = null;
		before();
		result = method.invoke(target, args);
		after();
		return result;
	}

	private void before() {
		System.out.println("before....");
	}

	private void after() {
		System.out.println("after....");
	}
}

    最后对代码进行测试

public class ProxyTest {
	public static void main(String[] args) {
		//首先生成我们自己定义的处理器实例
		//默认对接口中的所有方法都是统一的代理实现
		MyHandler my = new MyHandler();
		//通过接口接受返回的代理对象
		//传入具体类的实现
		Hello hello = (Hello)my.bind(new HelloImpl());
		//调用这个代理类中的方法
		//接口中的所有方法都动态的加上了一定的功能
		hello.sayHello();	
	}
}

   执行结果

before....
Hello
after....

   问题?动态代理给接口中的所有方法都统一的加上了指定的功能,能不能进行细粒度的控制?比如有的方法加上指定的功能,有的方法不变?或者能不能每个方法加的功能都不一样?我想这也只有通过静态代理才能实现了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics