zoukankan      html  css  js  c++  java
  • 基于接口的动态代理和基于子类的动态代理

    动态代理:在不修改源码的基础上,对原有方法的增强。


    准备接口:

    Iproducer.interface:

    public interface Iproducer {
        public double saleProducer(double money);
    }

    接口动态代理

    producer.java

    public class producer implements Iproducer{
        public double saleProducer(double money) {
            System.out.println("卖出"+money);
            return money;
        }
    }

    测试:

    client.javapackage proxy;

    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * 基于接口的动态代理
     */
    public class client {
        public static void main(String[] args) {
            final producer producer=new producer();
            Iproducer p =(Iproducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().getInterfaces(), new InvocationHandler() {
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Object value = null;
              //只有一个参数 Double money
    = (Double) args[0]; if ("saleProducer".equals(method.getName())) { money = 0.8 * money; value = method.invoke(producer, money); } return value; } }); p.saleProducer(10000); } }

    分析:通过getClass()、getClassLoad()加载字节码文件,再加载接口字节码文件(返回类型是接口类型)。在匿名内部类定义invoke方法

    该方法在代理对象调用被代理对象方法时都会执行,传入的参数也会传入该方法,然后进行自定义的增强。返回值与被代理对象的方法的返回值一致。


    子类 动态代理

    producer.java

    public class producer {
        public double saleProducer(double money) {
            System.out.println("卖出"+money);
            return money;
        }
    }

    client.java

    package proxy;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    /**
     * 基于子类的动态代理
     */
    public class client2 {
        public static void main(String[] args) {
            final  producer2 producer2=new producer2();
    
            producer2 p = (producer2) Enhancer.create(producer2.getClass(), new MethodInterceptor() {
                public Object intercept(Object o, Method method, Object[] args,
                                        MethodProxy methodProxy) throws Throwable {
                    Object value = null;
                    Double money = (Double) args[0];
    
                    if ("saleProducer".equals(method.getName())) {
                        money = 0.8 * money;
                        value = method.invoke(producer2, money);
                    }
                    return value;
                }
            });
            p.saleProducer(10000);
    
        }
    }

    分析与上基本一致,要使用cglib.jar包

  • 相关阅读:
    【OpenCV入门指南】第一篇 安装OpenCV
    java.lang.Math中的基本方法
    padding与margin的差别
    怎样做到从程序猿到管理者的跳跃
    秒杀多线程第四篇 一个经典的多线程同步问题
    NETSH WINSOCK RESET这条命令的含义和作用?
    如何在windows系统自带命令查看硬件信息?
    centos6.5 无线网卡配置
    ctagst简单应用,将Vim改造:Ctags,Taglist,Cscope,OmniCppComplete,SuperTab,Winmanager,NERDTree,MiniBufExplorer,vimrc
    lsof 拥有更多的功能
  • 原文地址:https://www.cnblogs.com/findlisa/p/11065298.html
Copyright © 2011-2022 走看看