欢迎来到DIVCSS5查找CSS资料与学习DIV CSS布局技术!

Java 动态代理类的实现

1、动态代理:为目标对象创建一个代理类,该代理类拥有目标对象的方法,属性,同时也可添加自己的方法,比如:日志的添加、校验等。

2、实现条件:在java中规定,要想产生一个对象的代理对象,那么这个对象必须要有一个接口,所以我们第一步就是设计这个对象的接口,在接口中定义这个对象所具有的行为(方法)

2、应用场景:当用户要调用一个类的方法时,用户可以通过调用代理,代理通过接口调用原来的类的方法,代理在把方法给用户前可以添加一些方法,如错误日志,用户类的方法运行的时间来监听类方法的性能。当代理完成时候就是当代理调用方法时候,就会启动InvocationHandler里的invoke方法(在测试类中代理类调用方法时有所体现)。

3、实例关键点:java在JDK1.5之后提供了一个"java.lang.reflect.Proxy"类,通过"Proxy"类提供的一个newProxyInstance方法用来创建一个对象的代理对象,如下所示:

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 

newProxyInstance方法用来返回一个代理对象,这个方法总共有3个参数,
ClassLoader loader用来指明生成代理对象使用哪个类装载器,
Class<?>[] interfaces用来指明生成哪个对象的代理对象,通过接口指定,
InvocationHandler h用来指明产生的这个代理对象要做什么事情。
所以我们只需要调用newProxyInstance方法就可以得到某一个对象的代理对象了。

4、实例如下:
1、目标对象接口:
public interface People {

    /**
     * 唱歌
     * @param name
     * @return
     */
    public String sing(String name);

    /**
     * 跳舞
     * @param name
     * @return
     */
    public String dance(String name);

}
2、实现接口的目标对象

/**
 * 目标类对象
 */
public class LiuDeHua implements People{

    @Override
    public String sing(String name) {

        return "唱"+name+"歌!好听!";
    }

    @Override
    public String dance(String name) {
        return "跳"+name+"舞!好看!";
    }
}
3、代理类的实现
/**
 * 目标类(LiuDeHua)代理类
 */
public class LiuDeHuaProxy {
    //类变量,代理类要代理的目标对象
    private People ldh = new LiuDeHua();

    public People getProxy() {
        return (People) Proxy.newProxyInstance(LiuDeHuaProxy.class
                .getClassLoader(), ldh.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method,
                                 Object[] args) throws Throwable {
                //此处可添加目标对象以外的方法。。。
                         
                //如果调用的是代理对象的sing方法
                if (method.getName().equals("sing")) {
                    
                    return method.invoke(ldh, args); //代理对象调用真实目标对象的sing方法去处理用户请求
                }
                //如果调用的是代理对象的dance方法
                if (method.getName().equals("dance")) {
                   
                    return method.invoke(ldh, args);//代理对象调用真实目标对象的dance方法去处理用户请求
                }

                return null;
            }
        });
    }

}
4、测试动态代理类调用过程
public class Test {
    public static void main(String[] args) {
        //代理类
        LiuDeHuaProxy proxy = new LiuDeHuaProxy();

        //获得代理对象
        People p = proxy.getProxy();

        //调用代理对象的sing方法
        String retValue = p.sing("冰雨");
        System.out.println(retValue);

        //调用代理对象的dance方法
        String value = p.dance("江南style");
        System.out.println(value);
    }

}

如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h57181.shtml