原文
Spring學(xué)習(xí)(五):動態(tài)代理的兩種實現(xiàn)方式(全網(wǎng)最容易懂)_P@ssW0rd的博客-CSDN博客
1、基于JDK的動態(tài)代理
基于接口的動態(tài)代理,用到的類是Proxy的newProxyInstance靜態(tài)方法創(chuàng)建,要求被代理對象至少實現(xiàn)一個接口,如果沒有,則不能創(chuàng)建代理對象。
2、基于cglib的動態(tài)代理
要導(dǎo)入cglib第三方庫,使用的類是Enhancer的create靜態(tài)方法創(chuàng)建,要求被代理類不能是最終類,即不能用final修飾,如String類。
三、代碼演示
1、首先創(chuàng)建一個IProduct接口,并創(chuàng)建被代理類,實現(xiàn)這個接口
IProduct
public interface IProduct {
String sell(Float money);
void afterSell();
}
public class Product implements IProduct {
@Override
public String sell(Float money) {
System.out.println("代理員交給工廠:"+money);
return "aaa";
}
@Override
public void afterSell() {
System.out.println("代理員做售后。。");
}
}
通過JDK來實現(xiàn)動態(tài)代理,創(chuàng)建一個消費者Consumer
這里我們直接通過匿名內(nèi)部類來實現(xiàn),當(dāng)然不是必須的
public class Consumer {
public static void main(String[] args) {
// 創(chuàng)建一個被代理對象
final Product product = new Product();
// 創(chuàng)建一個代理對象,并在InvocationHandler的invoke方法里面,對被代理類的方法做增強
IProduct proxyProduct = (IProduct) Proxy.newProxyInstance(product.getClass().getClassLoader(), product.getClass().getInterfaces(), new InvocationHandler() {
// 實現(xiàn)具體的增強操作
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 獲取方法在運行中可能產(chǎn)生的返回值
Object returnValue = null;
Float money = (Float) args[0];
if("sell".equals(method.getName())){
// 執(zhí)行具體的方法
returnValue = method.invoke(product, money*0.8F);
}
return returnValue;
}
});
System.out.println(proxyProduct.sell(1000F));
}
}
IProduct proxyProduct = (IProduct) Proxy.newProxyInstance(product.getClass().getClassLoader(), product.getClass().getInterfaces(), new InvocationHandler() {
}
ClassLoader loader獲取被代理類的類加載器。
Class<?>[] interfaces獲取被代理類的實現(xiàn)接口的數(shù)組。
InvocationHandler h在invok方法中對方法做增強處理。
invoke方法的三個參數(shù)
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
}
3、通過cglib來實現(xiàn)動態(tài)代理,創(chuàng)建一個消費者Consumer
public class Consumer {
public static void main(final String[] args) {
// 創(chuàng)建一個被代理對象,這里要求必須是final
final Product product = new Product();
Product proxyProduct =(Product) Enhancer.create(product.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Float money = (Float) objects[0];
Object returnValue = null;
if("sell".equals(method.getName())){
returnValue = method.invoke(product, 0.8f * money);
}
return returnValue;
}
});
System.out.println(proxyProduct.sell(1000f));
}
}
Enhancer.create的2個參數(shù)
Product proxyProduct =(Product) Enhancer.create(product.getClass(), new MethodInterceptor() {
}
Class type被代理類的class文件
Callback callback一個Callback接口,我們通常使用MethodInterceptor接口,繼承了Callback接口
ntercept方法的參數(shù)
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
}
Method method當(dāng)前方法
Object[] objects方法用到的參數(shù)數(shù)組