今天穿插讲一下两个方式的动态代理
1.基于接口的动态代理
2.基于子类的动态代理
含有两个方法
1.销售商品
2.提供售后服务
package cn.kitey.proxy;
/**
* 一个生产厂家
*/
public class Producer implements ProducerInterface{
/**
* 销售
*/
public void saleProduct(double money){
System.out.println("销售产品,获取金钱:" + money);
}
/**
* 售后服务
* @param money
*/
public void afterService(double money){
System.out.println("提供售后服务:" + money);
}
}
现在创建的一个类:代表消费者直接在厂商购买商品
现在产生了一个需求:
厂商与消费者之间产生了经销商,则通过经销商,生产厂家只能拿到消费者消费数额的百分之八十,所以我们这时可以使用动态代理
关于动态代理的注解都在下面代码中:
我强调一下最重要的就是填写动态代理的增强方法
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
package cn.kitey.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) {
//匿名内部类访问时要求是最终的
Producer producer = new Producer();
producer.saleProduct(1000);
}
}
添加了基于接口的动态代理类
package cn.kitey.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();
/**
* 动态代理:
* 特点:字节码随意创建,随用随加载
* 作用:不修改源码的基础上,对方法进行加强
* 分类:
* 基于接口的动态代理
* 基于子类的动态代理
*
* 基于接口的动态代理;
* 涉及的类:Proxy
* 如何创建代理对象:
* 使用Proxy类中的newProxyInstance
* 创建代理对象的要求:
* 被代理的对象至少实现一个接口,如果没有,则不能进行实现
* newProxyInstance中的方法参数
* ClassLoader:类加载器
* 适用于加载代理对象的字节码,和被带你的对象使用相同的类加载器(固定写法)
* Class[]:字节码数组
* 是用于代理对象和被代理对象拥有相同的方法(固定的写法)
* InvocationHandler:用于提供增强的代码
* 让我们写如何代理,一般都是些一个接口的实现类,通常情况下是匿名类,但不是必须的
* 此接口的实现类谁用谁写
*/
//(近似于经销商)
ProducerInterface producerInterface = (ProducerInterface) Proxy.newProxyInstance(
producer.getClass().getClassLoader(),
producer.getClass().getInterfaces(),
new InvocationHandler() {
/**
* 作用:执行被代理对象的任何接口方法都会经过该方法
* @param proxy 代理对象的引用(一般不用)
* @param method 当前执行的方法
* @param args 当前执行方法所需要的参数
* @return 和被代理对象方法有相同的返回值
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取以前的金钱数据
double oldMoney = (Double) args[0];
//提供增强代码
Object newMoney = null;
//判断是不是销售产品
if("saleProduct".equals(method.getName())){
newMoney = method.invoke(producer, oldMoney * 0.8);
}
return newMoney;
}
});
/**
* 现在存在一个需求,经过了经销商,产家只能获取百分之八十的钱
*/
producerInterface.saleProduct(1000);
}
}
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_3</version>
</dependency>
</dependencies>
其中使用Enhancer类中的create方法进行对象的代理
create中只用两个参数
class(字节码), Callback(提供代码的增强)
new MethodInterceptor()方法增强的内部类
package cn.kitey.cglib;
import cn.kitey.proxy.Producer;
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 ClientCglib {
public static void main(String[] args) {
final Producer producer = new Producer();
/**
* 基于子类的动态代理;
* 涉及的类:Enhancer
* 提供者:第三方cglib类库
* 如何创建代理对象:
* 使用Enhancer类中的create方法
* 创建代理对象的要求:
* 被代理的对象不能是最终实现类
* create方法中的方法参数
* Class:字节码
* 用于指定被代理对象的字节码
* Callback:提供增强代码
* 一般书写的为该接口的实现类:MethodInterceptor(方法拦截)
*
*/
Producer proEnhancer= (Producer) Enhancer.create(producer.getClass(), new MethodInterceptor() {
/**
* 执行被代理对象的任何方法都会经过该方法
* @param proxy
* @param method
* @param args
* @param methodProxy 当前执行方法的代理对象
* @return
* @throws Throwable
*/
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//这里提供增强方法
Object newMoney = null;
//获取被代理对象的参数
double oldMoney = (Double) args[0];
//判断执行的方法
if("saleProduct".equals(method.getName())){
newMoney = method.invoke(producer, oldMoney * 0.5);
}
return newMoney;
}
});
proEnhancer.saleProduct(1000);
}
}
这个是生产者只拿到了百分之五十的消费者消费的数额
运行结果图:
以上就是一个简单的动态代理的讲解,希望我们都能变的更加优秀!