JAVA反射_代理

来源:互联网 发布:电脑实用软件推荐 编辑:程序博客网 时间:2024/06/07 06:21

一、什么是动态代理

动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实。代理一般会实现它所表示的实际对象的接口。代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统的实际功能,代理对象对客户隐藏了实际对象。客户不知道它是与代理打交道还是与实际对象打交道。

目的:主要用来做方法的增强,让你可以在不修改源码(不用改变这个方法的签名,原来调用这个方法的类依然能正常工作)的情况下,增强一些方法。在方法执行前后做任何你想做的事情(甚至根本不去执行这个方法),因为在InvocationHandler的invoke方法中,你可以直接获取正在调用方法对应的Method对象,具体应用的话,比如可以添加调用日志,做事务控制等。

还有一个有趣的作用是可以用作远程调用,比如现在有Java接口,这个接口的实现部署在其它服务器上,在编写客户端代码的时候,没办法直接调用接口方法,因为接口是不能直接生成对象的,这个时候就可以考虑代理模式(动态代理)了,通过Proxy.newProxyInstance代理一个该接口对应的InvocationHandler对象,然后在InvocationHandler的invoke方法内封装通讯细节就可以了。具体的应用,最经典的当然是Java标准库的RMI,其它比如hessian,各种webservice框架中的远程调用,大致都是这么实现的。
而像 AspectJ 这种 AOP 刚不同,它直接把人家的 class 代码修改了,它就不需要使用代理。
这些在新的 JDK 6 中都可以通过 Instrument 来做到,不过也是个通用的方法,还得通过规则来定制什么情况下处理,什么时候不处理。

二、jdk的动态代理
  目前Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。 其实现主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。 

Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现。

动态代理是很多框架和技术的基础, spring 的AOP实现就是基于动态代理实现的。了解动态代理的机制对于理解AOP的底层实现是很有帮助的。



平常写的代码,一般是一个对象直接持有另外一个对象的引用,称为

静态代理

public class StaticProxyMain {    //这里传入的是接口类型的对象,方便向上转型,实现多态    public static void consumer(ProxyInterface pi){        pi.say();    }    public static void main(String[] args) {        StaticProxyMain.consumer(new ProxyObject());    }}//代理接口interface ProxyInterface{    void say();}//被代理者class RealObject implements ProxyInterface{    //实现接口方法    @Override    public void say() {        System.out.println("say");    }}//代理者class ProxyObject implements ProxyInterface{    @Override    public void say() {        System.out.println("hello proxy");        new RealObject().say();        System.out.println("this is method end");    }}


动态代理:

例子1:

public class DProxyMain {    public static void main(String[] args) {        ArrayList<String> content = new ArrayList<>();        MyInvocationHandler handler = new MyInvocationHandler(content);        Object proxy = Proxy.newProxyInstance(null, new Class[]{List.class}, handler);        if (proxy instanceof List) {            System.out.println("proxy is list");            List<String> mlist = (List<String>) proxy;            mlist.add("one");            mlist.add("two");            mlist.add("three");            mlist.add("apple");        }        System.out.println("proxy:"+proxy.toString());        System.out.println("content:"+content.toString());    }}class MyInvocationHandler implements InvocationHandler {    private Object target;    public MyInvocationHandler(Object target) {        this.target = target;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("method name:"+method.getName());        if (method.getName().equals("add")) {            if (args[0].equals("apple")) {                return false;            }        }        return method.invoke(this.target, args);    }}

例子2:

public class DynamicProxyMain {    public static void main(String[] args) {        RealObject realObject = new RealObject();        ProxyInterface proxyInterface = (ProxyInterface) Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(), new Class[]{ProxyInterface.class}, new ProxyObject(realObject));        proxyInterface.say();    }}//代理接口interface ProxyInterface{    void say();}//被代理类class RealObject implements ProxyInterface {    @Override    public void say() {        System.out.println("I'm talking...");    }}//代理类,实现InvocationHandler 接口class ProxyObject implements InvocationHandler {    private Object target = null;    public ProxyObject(Object proxied){        this.target  = proxied;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("method name:"+method.getName());        return method.invoke(this.target, args);    }}


应用场景:

1. 利用动态代理实现设计模式,修饰器和适配器

2. AOP编程(Spring AOP)


原创粉丝点击