web框架学习前复习——动态代理

                            动态代理
动态代理涉及的内核思想比较深,现在暂时无法理解其在java虚拟机中的具体实行过程但是可以做大概的理解。有动态代理就有静态代理,其实动态代理的产生就是为了解决静态代理所产生的大量实例类。在静态代理中代理类和结果类实现了共同的接口,我们通过代理类来访问结果类。用户可以在代理类的方法中进行自定义可以在进行结果类之前和之后增加自己的操作。最形象的例子就是火车站的售票点和街道代售点了。它们的功能是一样的代理其实就是一个中介功能。随着类的增加会使得系统中存在着大量的实例类,不利于维护。
动态代理的思想其实很简单,你需要使用代理类增加的条件就创建一个代理实例类,使用完后销毁该实例。直接调用结果类的方法则不产生代理类直接调用结果类的方法。通过一个InvocationHandler接口来实现。代理类实现InvocationHandler接口和自己代理的接口方法产生一个动态代理类。在调用代理接口的方法前InvocationHandler中的方法invoke都会进行拦截,如果需要代理类则创建一个代理类。如果只是执行结果类的方法则直接执行虚拟机事先加载的结果类方法。这样可以提高效率并且不会产生大量实例类。
public interface Human {
    void sing(float money);
    void dance(float money);
}
public class SpringBrother implements Human {

    public void sing(float money) {
        System.out.println("美女唱歌的费用"+money);
    }

    public void dance(float money) {
        System.out.println("美女跳舞的费用"+money);
    }

}
public class Client {

    public static void main(String[] args) {
        final Human sb = new SpringBrother();
        //代理人:如何动态产生代理人
        /*
    ClassLoader loader:动态代理,必须有字节码class。加到内存中运行,必须有类加载器。固定:和被代理人用的是一样的
        Class<?>[] interfaces:代理类要实现的接口,要和被代理对象有着相同的行为。固定:和被代理人用的是一样的
        InvocationHandler h:如何代理。他是一个接口。
         */
        //产生代理类,得到他的实例
    Human proxyMan = (Human)Proxy.newProxyInstance(sb.getClass().getClassLoader(), 
            sb.getClass().getInterfaces(), 
            new InvocationHandler() {
                //匿名内部类,完成具体的代理策略
                //调用代理类的任何方法,都会经过该方法。  拦截
                /*
                 Object proxy:对代理对象的引用。
                 Method method:当前执行的方法
                 Object[] args:当前方法用到的参数
                返回值:当前调用的方法的返回值
                 */
            public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
                //判断出场费
                if("sing".equals(method.getName())){
                //唱歌
                    float money = (Float)args[0];
                    if(money>10000){
                        method.invoke(sb, money/2);
                    }
                }
                if("dance".equals(method.getName())){
                    //唱歌
                    float money = (Float)args[0];
                        if(money>20000){
                            method.invoke(sb, money/2);
                        }
                }
                return null;
            }
        }
        );
        proxyMan.sing(20000);
        proxyMan.dance(100000);
    }

}

猜你喜欢

转载自blog.csdn.net/u011456867/article/details/52138963
今日推荐