接口代理:
接口:
package cn.mepu.proxy;
/**
* @author shkstart
* @create 2019-11-09 13:10
*/
public interface IProducer {
/**
* 销售
* @param money
*/
public void saleProduct(float money);
/**
* 售后
* @param money
*/
public void afterService(float money);
}
实现类:
1 package cn.mepu.proxy;
2
3 /**
4 * 生产者类
5 * @author shkstart
6 * @create 2019-11-09 13:06
7 */
8 public class Producer implements IProducer {
9
10 /**
11 * 销售
12 * @param money
13 */
14 public void saleProduct(float money){
15 System.out.println("销售产品,并拿到钱"+money);
16 }
17
18 /**
19 * 售后
20 * @param money
21 */
22 public void afterService(float money){
23 System.out.println("提供售后服务,并拿到钱"+money);
24 }
25 }
动态增强:
package cn.mepu.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 消费者
* @author shkstart
* @create 2019-11-09 13:12
*/
public class Client {
public static void main(String[] args) {
final Producer producer = new Producer();
/**
* 动态代理:
* 特点:字节码随用随创建,随用随加载
* 作用:不改变源码对方法增强
* 分类:
* 基于接口的动态代理:
* 涉及类:Proxy
* 提供者:JDK官方
* 如何创建动态代理:
* 使用Proxy的newProxyInstance方法
* 创建代理对象的要求:
* 被代理类至少实现一个接口,如果没有不能使用
* newProxyInstanse方法参数:
* ClassLoader:类加载器
* 用于加载代理对象子字节码,和被代理对象使用相同的类加载器,固定写法
* Class[]:字节码数组
* 用于代理对象和被代理对象有相同的方法,固定写法
* InvocationHandler:用于提供增强的代码
* 写如何代理,一般写一个该接口的实现类,通常是匿名内部类,但不是必须
* 此接口的实现类是谁用谁写
*
* 基于子类的动态代理
*
*/
IProducer proxyProducer = (IProducer) Proxy.newProxyInstance(Producer.class.getClassLoader(), Producer.class.getInterfaces(), new InvocationHandler() {
/**
* 执行被代理对象的任何接口方法都会经过该方法
* @param proxy 代理对象的引用
* @param method 当前执行的方法
* @param args 当前执行方法所需的参数
* @return 和被代理对象有相同的返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//提供增强代码
Object returnValue = null;
//1.获取方法执行的参数
Float money = (Float) args[0];
//2.判断当前方法是不是销售
if ("saleProduct".equals(method.getName())){
returnValue = method.invoke(producer,money*0.8f);
}
return returnValue;
}
});
proxyProducer.saleProduct(10000f);
}
}
类代理:
导入cglib依赖
被增强类:
package cn.mepu.cglib;
/**
* 生产者类
* @author shkstart
* @create 2019-11-09 13:06
*/
public class Producer {
/**
* 销售
* @param money
*/
public void saleProduct(float money){
System.out.println("销售产品,并拿到钱"+money);
}
/**
* 售后
* @param money
*/
public void afterService(float money){
System.out.println("提供售后服务,并拿到钱"+money);
}
}
动态增强:
package cn.mepu.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* 消费者
*
* @author shkstart
* @create 2019-11-09 13:12
*/
public class Client {
public static void main(String[] args) {
final Producer producer = new Producer();
/**
* 动态代理:
* 特点:字节码随用随创建,随用随加载
* 作用:不改变源码对方法增强
* 分类:
* 基于子类的动态代理:
* 涉及类:Enhancer
* 提供者:第三方cglib库
* 如何创建动态代理:
* 使用Enhancer的create方法
* 创建代理对象的要求:
* 被代理类不能是最终类
* create方法参数:
* Class:字节码
* 指定被代理对象的字节码
* Callback:用于提供增强的代码
* 写如何代理,一般写一个该接口的实现类,通常是匿名内部类,但不是必须
* 此接口的实现类是谁用谁写
* 写的该接口的子接口实现类:MethodInterceptor
*
*/
Producer cglibProducer = (Producer) Enhancer.create(producer.getClass(), new MethodInterceptor() {
/**
* 执行被代理对象的任何方法都会执行该方法
* @param o 代理对象的引用
* @param method 当前执行的方法
* @param objects 当前执行方法所需的参数
* @param methodProxy 当前执行方法的代理对象
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//提供增强代码
Object returnValue = null;
//1.获取方法执行的参数
Float money = (Float) objects[0];
//2.判断当前方法是不是销售
if ("saleProduct".equals(method.getName())) {
returnValue = method.invoke(producer, money * 0.8f);
}
return returnValue;
}
});
cglibProducer.saleProduct(10000);
}
}