基于接口的动态代理和基于子类的动态代理

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


准备接口:

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包

 

posted @ 2019-06-21 16:19  findlisa  阅读(577)  评论(0编辑  收藏  举报