(2019-3-12) java静态代理与动态代理

什么是代理?

个人认为代理模式就是首先由一个接口,并且由若干个实现这个接口的具体类,然后再额外创建一个proxy类(代理类),再这个类中实现接口中的方法(获取代理服务),最后再所继承的方法中调用其他具体类的方法(代理)。
就好比现在的微商,在网络中,各种微商通过代理销售背后厂家的商品,在网络的另一端,客户们不知道厂家是谁。
我们把微商代理和厂家进一步抽象,前者可抽象为代理类,后者可抽象为委托类(被代理类)。通过使用代理,通常有两个优点,并且能够分别与我们提到的微商代理的两个特点对应起来:
优点一:可以隐藏委托类的实现;
优点二:可以实现客户与委托类间的解耦,在不修改委托类代码的情况下能够做一些额外的处理。

(2019-3-12) java静态代理与动态代理

静态代理

若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的。 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类。

1.第一步,创建Weapon.java接口

public interface Weapon {
    public void attack(int a);
}

2.第二步,创建具体实现类Vectory.java

public class Vectory implements Weapon {
    @Override
    public void attack(int a) {
        System.out.println("伤害:"+a+"/发");
    }
}

3.第三步,创建代理类Proxy.java

public class Proxy implements Weapon {
    Weapon weapon ;

    //构造方法
    public Proxy(Weapon weapon) {
        this.weapon = weapon;
    }

    public void prepare(){
        System.out.println("预备");
    }
    @Override
    public void attack(int a) {
        prepare();
        weapon.attack(a);
        after();
    }
    public void after(){
        System.out.println("结束");
    }
}

4.测试

public class App 
{
    public static void main( String[] args )
    {
        Proxy proxy = new Proxy(new Vectory());
        proxy.attack(23);
    }
}

预备
伤害:23/发
结束

Process finished with exit code 0

动态代理(dynamic proxy)

动态代理是指动态的在内存中构建代理对象(需要我们制定要代理的目标对象实现的接口类型),即利用JDK的API生成指定接口的对象,也称之为JDK代理或者接口代理。

1.切面类

public class MyTransaction {
    public void prepare(){
        System.out.println("我是代理前");
    }
    public void after(){
        System.out.println("我是代理后");
    }
}

2.创建实现InvocationHandler接口的类

public class DynamicProxy implements InvocationHandler {
    //目标类
    Object object;
    //切面类
    MyTransaction myTransaction;
    public DynamicProxy(Object object,MyTransaction myTransaction) {
        this.object = object;
        this.myTransaction=myTransaction;
    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        myTransaction.prepare();
        method.invoke(this.object,objects);
        myTransaction.after();
        return null;
    }
}

3.测试类

public class DynamicTest {
    public static void main(String[] args) {
        //要代理的真实对象
        Weapon weapon = new Vectory();
        //切面类
        MyTransaction myTransaction = new MyTransaction();
        //获取代理类
        DynamicProxy dynamicProxy = new DynamicProxy(weapon,myTransaction);
        /**
         * 通过proxy类的newProxyInstance方法创建代理对象
         * 第一个参数:weapon.getClass().getClassLoader(),使用objectInterceptor对象的classloader对象来加载我们的代理对象
         * 第二个参数:weapon.getClass().getInterfaces(),这里为代理类提供的接口是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口
         * 中的所有方法
         * 第三个参数:objectInterceptor,我们将代理对象关联到上面的事务类中
         */
        Weapon weapon1 = (Weapon) Proxy.newProxyInstance(weapon.getClass().getClassLoader(),
                weapon.getClass().getInterfaces(), dynamicProxy);
        weapon1.attack(1);
    }
}

(2019-3-12) java静态代理与动态代理

总结:静态与动态代理的比较

静态代理:代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。如果接口增加一个方法,则除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。

动态代理:如果接口增加一个方法,则只需要实现类实现此方法即可,代理类不需要改动。