动态代理(一)

代理是基本的设计模式之一,说一说它的一个定义:它是你为了提供额外的不同操作,而插入的用来代替“实际”对象的的对象。
首先面向接口编程是我们代理的开始,接口一般我们用来做方法回调,和搭架子用。
public interface Interface {
    void doSomthing();
    void doSomethingElse(Object proxied);

}
再写一个实体类来实现它做点事

public class RealObject implements Interface {
    
    
    @Override
    public void doSomthing() {
        System.out.println("doSomething");
    }

    @Override
    public void doSomethingElse(Object proxied) {
        System.out.println("doSomethingElse"+proxied);
    }
}

现在写个main方法来用一用最简单的代理

public class SimpleProxyDemo {
    public static void main(String[] args) {
        consumer(new RealObject());
        consumer(new SimpleProxy(new RealObject()));
    }
    public static void consumer(Interface iface){
        iface.doSomthing();
        iface.doSomethingElse("  lala");
    }
}

我们运行的结果:

doSomething
doSomethingElse  lala
SimpleProxy doSomeThing
doSomething
SimpleProxy doSomethingElse
doSomethingElse  lala

这就是代理,在任何时刻,只要你想要将额外的操作从“实际”对象中分离到不同的地方,特别是当你希望能够很容易地做出修改,从没有使用额外操作转为使用这些操作,或者反过来时。
Java的动态代理:可以动态地创建代理并动态地处理对所代理方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作是揭示调用的类型并确定相应的对策。

public class DynamicProxyHandler implements InvocationHandler {
    
    
    private Object proxied;
    public static int number = 0;
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        number++;
        System.out.println("***proxy"+proxy.getClass()+",method:"+method+",args"+args+"number"+number);
        if (args!=null)
            for (Object arg : args) {
                System.out.println(" "+arg);
            }
        return method.invoke(proxied,args);
    }

    public DynamicProxyHandler(Object proxied) {
        this.proxied = proxied;
    }
}

然后我们写个main方法试试效果

public class SimpleDynamicProxy {
    public static void main(String[] args) {
        RealObject realObject = new RealObject();
        consumer(realObject);
        Interface anInterface = (Interface) Proxy.newProxyInstance(Interface.class.getClassLoader(),
                new Class[]{Interface.class},
                new DynamicProxyHandler(realObject));
        consumer(anInterface);
    }
    public static void consumer(Interface iface){
        iface.doSomthing();
        iface.doSomethingElse("lala");
    }
}

运行结果:

doSomething
doSomethingElselala
***proxyclass com.sun.proxy.$Proxy0,method:public abstract void main.Interface.doSomthing()  args: null  number:1
doSomething
***proxyclass com.sun.proxy.$Proxy0,method:public abstract void main.Interface.doSomethingElse(java.lang.Object)  args: [Ljava.lang.Object;@7ea987ac  number:2
 lala
doSomethingElselala

相信第一次接触动态代理的小伙伴一脸懵逼,什么玩意啊。好的我们来解释一下,其实这就是java对动态代理的一个实现,我们不用麻烦的去写代理类了,直接使用封装好的东西。
通过调用静态方法Proxy.newInstance()可以创建动态代理,这个方法需要得到一个类加载器,(可以通过已经被加载的类中获得,然后传递给它),一个你希望实现的接口列表(一定是接口),以及InvocationHandler接口的实现。还有一个实际的对象,我们要代理的对象。
每次调用我们动态代理类的里的方法,都会调用实现接口InvocationHandler的invoke方法,从这个方法里我们就可以做一些额外操作,这些操作可以通过判断方法名称来做区别method.getName()就可以得到当前调用的方法名。
对于得到的方法method对象调用method.invoke(proxied,args),学过反射就不难理解了。其实就是对象方法的调用
好了,这就是Java的动态代理,希望以后见到动态代理大家都不要懵逼。

猜你喜欢

转载自blog.csdn.net/huihuishou_su/article/details/78187286