동적 프록시 -로드에 사용되는 바와 같이, 생성로에서 사용 된 바이트 코드를 포함 할 수있다.
바이트 코드 하나를 만들어, 마무리 로딩 - 정적 프록시. (예 : 장식 패턴)
1. 제조업체 인터페이스 :
package proxy;
public interface IProducer {
/**
* 销售
* @param money
*/
public void saleProduct(float money);
/**
* 售后
* @param money
*/
public void afterService(float money);
}
2. 제조사 구현 클래스 :
package proxy;//代理
/**
* Producer生产商
*
* 1个生产商:
* 原来做的事:
* 卖产品 参数:钱
* 售后
*
*/
public class Producer implements IProducer{
/**
* 销售
* @param money
*/
public void saleProduct(float money){
System.out.println("销售产品,后 拿到钱:"+money);
}
/**
* 售后
* @param money
*/
public void afterService(float money){
System.out.println("提供售后服务,后 拿到钱:"+money);
}
}
3. 고객은 컴퓨터 클래스의 주요 메소드를 구입 :
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.SQLOutput;
/**
* 顾客 找代理 买电脑
*/
public class Client {
public static void main(String[] args) {
//以前是找生产商
final Producer producer = new Producer();//内部类调用的外部变量必须是final修饰
/**
* 现在找 动态代理:
* 特点:字节码随用随创建,随用随加载
* 作用:不修改源码 的基础上 对某方法增强
* 分类:
* 基于 接口 的动态代理
* 基于 子类 的动态代理
*
* 基于 接口 的动态代理:
* 涉及的类:Proxy
* 提供者:JDK官方
* 创建代理对象的 要求:
* 被代理对象=生产厂家 最少要实现 1个接口——否则不能代理
* 如何创建 以上这个 代理对象:
* 用Proxy类的 newProxyInstance方法
* newProxyInstance方法的 参数:
* ClassLoader=类加载器
* 加载 代理对象 的 字节码,和被代理对象 用着相同的加载器【固定写法】
* Class[]=字节码数组
* 获取到生成厂家的所有接口,使被代理与代理有相同的方法【固定写法】
* InvocationHandler 增强的代码
* 写如何代理——通常写个该接口的实现类匿名内部类【不必须】
* 谁用代理谁写,此时顾客用 就顾客来写 */
//拿到代理对象 返回值为object 强转为生成厂家类型
IProducer proxyProducer=(IProducer)Proxy.newProxyInstance(
producer.getClass().getClassLoader(),
producer.getClass().getInterfaces(),
new InvocationHandler() {//增强代码
/**
* 执行 生成厂家的 任何接口中方法 前 都会先经过该方法的增强
* 相当于 有拦截功能
* @param proxy 代理对象 的引用【以下代理对象在卖电脑,代理对象是proxyProducer】
* @param method 当前执行的 方法【以下调用的saleProduct】
* @param args 当前执行方法 的参数 【以下调用中的10000元】
* @return 和生成厂家 有相同返回值【此处我们在这改变他的返回值为8000】
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//提供增强的 代码: 让生成厂家只拿到8000
Object returnValue=null;
//拿到正确数据类型 的参数
Float money=(Float)args[0];
//判断当前方法 是否为 销售:
if("saleProduct".equals(method.getName())){
//第1个参数producer 来执行method方法,第2个参数 method的参数
returnValue=method.invoke(producer,money*0.8f);//
}
return returnValue;
}
});
//用以上拿到的 代理对象 来卖电脑 售价10000元
proxyProducer.saleProduct(10000f);
}
}
-------------------------------------------- ---- 실행 결과 ----------------------------------------------