基于接口的动态代理和基于子类的动态代理
动态代理:在不修改源码的基础上,对原有方法的增强。
准备接口:
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包