基於接口的動態代理
IProducer接口
/**
* <p>
* 廠家對代理商的要求規範
*/
public interface IProducer {
/**
* 銷售
*
* @param money
*/
void saleProducer(Float money);
/**
* 售後
*
* @param money
*/
void afterService(Float money);
}
Producer
/**
* <p>
* 生產者
*/
public class Producer implements IProducer{
/**
* 銷售
*
* @param money
*/
@Override
public void saleProducer(Float money) {
System.out.println("銷售產品,並拿到" + money + "元");
}
/**
* 售後
*
* @param money
*/
@Override
public void afterService(Float money) {
System.out.println("提供售後服務,收取" + money + "元");
}
}
動態代理
public class Client {
public static void main(String[] args) {
final Producer producer = new Producer();
//producer.saleProducer(10000f);
/**
* 動態代理:
* 特點:字節碼隨用隨創建,隨用隨加載
* 作用:不修改源碼的基礎上對方法進行增強
* 分類:
* 基於接口的動態代理
* 基於子類的動態代理
* 基於接口的動態代理 Proxy.newProxyInstance();
* 要求:被代理類至少實現一個接口
* 參數:
* ClassLoader:用於加載代理對象字節碼,和被代理對象使用相同的類加載器 固定寫法
* Class<?>[]:讓代理對象和被代理對象有相同的方法 固定寫法
* InvocationHandler:用於提供增強的代碼
*/
//返回值要是一個接口而不是實現類
IProducer proxyInstance = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),
producer.getClass().getInterfaces(), new InvocationHandler() {
/**
*執行被代理的對象的任何接口方法都會經過該方法
* @param proxy 代理對象的引用
* @param method 當前執行的方法
* @param args 當前執行方法所需的參數
* @return 和被代理對象有相同的返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* method.invoke()被代理對象的方法
* 匿名內部類訪問外部成員變量時,外部成員用final修飾
*/
Object returnValue = null;
//1.獲取方法執行的參數
Float money = (Float) args[0];
//2.判斷當前方法是不是saleProducer
if ("saleProducer".equals(method.getName())) {
returnValue = method.invoke(producer, money * 0.8f);
}
return returnValue;
}
});
proxyInstance.saleProducer(10000f);
}
}
基於子類的動態代理
Producer
*/
public class Producer {
/**
* 銷售
*
* @param money
*/
public void saleProducer(Float money) {
System.out.println("銷售產品,並拿到" + money + "元");
}
/**
* 售後
*
* @param money
*/
public void afterService(Float money) {
System.out.println("提供售後服務,收取" + money + "元");
}
}
動態代理
public class Client {
public static void main(String[] args) {
final Producer producer = new Producer();
//producer.saleProducer(10000f);
/**
* 動態代理:
* 特點:字節碼隨用隨創建,隨用隨加載
* 作用:不修改源碼的基礎上對方法進行增強
* 分類:
* 基於接口的動態代理
* 基於子類的動態代理
* 基於子類的動態代理 Enhancer.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.判斷當前方法是不是saleProducer
if ("saleProducer".equals(method.getName())) {
returnValue = method.invoke(producer, money * 0.7f);
}
return returnValue;
}
});
cglibProducer.saleProducer(10000f);
}
}