码迷,mamicode.com
首页 > 编程语言 > 详细

Java特性-动态代理

时间:2016-08-11 01:03:48      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:

代理在开发中无处不在:

我们完成一个接口开发A,接口下有很多个实现类,这些类有些共同要处理的部分,比如每一个类都定义了接口A中的方法getXX(String name)。我现在想把每次调用某个实现类的getXX方法时传的参数name记录在数据库某个表里,可问题是,,我们总不能在每个实现类里面去添加一个这样的处理模块吧?工作量太大了,把该处理逻辑写到一个static的工具类里面,然后每个实现类再去调用也挺麻烦。况且这个处理是给改接口专门使用的,放在工具类里也不合适啊。。

好办,我再写一个实现接口A的类B,此类的作用:

  1. 对外提供一个getXXX(String name)方法,此方法就是前面提到的那些实现类中的具体方法;
  2. 每当别的类调用它的getXXX(String name)方法时,都做一个处理,即记录name到数据库里;

代码如下(静态代理)

接口:

public interface A{
    public Object getObj(String name);
}

实现类:

public class AaImpl implements A
{
public Object getObj(String name)
{
return "function from Aa"
}
}

public class AbImpl implements A
{
public Object getObj(String name)
{
  
return "function from Ab"
}
}

代理类:

public class delegator implements A{

    ABFactory ab = new ABFactory();
    A  a = ab.get(n);

    public Object getObj(String name){
        //此处记录name到数据库
     ...
     //此处开始执行get方法 return a.getObject(name); } }

上面的ABFactory负责生产A的实现类,通过get(n)中的参数,获得相应的对象;

采用以上方式,在少量实现类时很简单,也更容易理解;可是随着应用功能增加,实现原先接口的类越来越多,总不能每次都去修改工厂类吧。。

所有,动态代理产生了。。除了上面两点作用外,动态代理为我们提供一个最简化开发的模式

例如,我们在某个需求驱动下又创建了一个实现类Ac,它也继承A,它的getObj方法自然也要记录参数到数据库。

我们只管把类写出来就好了,之后被调用交给动态代理,它会帮我们处理好,别的代码都不需要动了。开发效率高,系统风险也低,开心。

接下来就是如何实现动态代理了:

委托类(代理)代码:

public class ProxyHandler implements InvocationHandler {
    private Object impObj;

    // 绑定委托对象,并返回代理类
    public Object bind(Object impObj) {
        this.impObj = impObj;
        /* 绑定该类实现的所有接口,取得代理类
        这个类就是实现A接口的某个类,在调用它的方法时
        就会先执行invoke中TODO-1部分的代码
        然后执行TODO-2,也就是getObj方法了
        其实之后也可以进行其他处理,处理代码在TODO-3中实现
        */
        return Proxy.newProxyInstance(impObj.getClass().getClassLoader(), impObj.getClass().getInterfaces(), this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        // TODO-1
        // TODO-2
        result = method.invoke(impObj, args);
        // TODO-3
        return result;
    }
}

当我们调用前面的类Ac时,只要如下:

ProxyHandler proxy = new ProxyHandler();
A c = (A) proxy.bind(new Ac);
c.getObj("XXX");

=============================================

此贴为本人原帖,帮助理解Java的动态代理特性,如有疏漏欢迎斧正,谢谢!

 

Java特性-动态代理

标签:

原文地址:http://www.cnblogs.com/tougherthanevil/p/5759377.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!