應用場景
比如進行日誌記錄、監控某個方法的運行時間、權限控制、事務管理 (調用方法前開啓事務, 調用方法後提交關閉事務 )、緩存優化 (第一次調用查詢數據庫,將查詢結果放入內存對象, 第二次調用, 直接從內存對象返回,不需要查詢數據庫 )等等,總的來說是執行目標方法前後都可以幹一些其他的事情,在不改動目標方法的前提下將目標方法與其他操作實現解耦。
區別
如果目標類有實現接口則用JDK動態代理,如果目標類沒有實現接口則用CGlib動態代理。
JDK動態代理
接口:
public interface PrepareWork {
//打開電腦
public void openCompare();
//輸入語言,開始擼代碼
public void LuCode(String language);
}
目標類:
public class RealWork implements PrepareWork {
@Override
public void openCompare() {
System.out.println("open computer......!");
}
@Override
public void LuCode(String language) {
System.out.println("今天用" + language +"擼代碼");
}
}
代理工廠:
public class ProxyFactory {
private Object object; // 目標對象
public ProxyFactory(Object object) {
this.object = object;
}
public Object getProxyInstance() {
return Proxy.newProxyInstance(
object.getClass().getClassLoader(),
object.getClass().getInterfaces(), new InvocationHandler() {
// proxy:表示我們代理的真實對象
// method:表示調用真實對象中的某個方法的metode對象
// args:調用真實對象方法裏所傳的參數
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
//在代理真實對象前我們可以添加一些自己的操作
System.out.println("調用方法前執行!");
//目標方法調用
Object obj = method.invoke(object, args);
System.out.println("方法執行完畢!");
return obj;
}
});
}
}
測試:
public class Test {
public static void main(String[] args) {
// 1.要代理的真實對象
RealWork prepareWork = new RealWork();//
PrepareWork proxy = (PrepareWork) new ProxyFactory(prepareWork).getProxyInstance();
proxy.openCompare();
System.out.println("-----------------------------分隔符-----------------------------");
proxy.LuCode("PAYTHON");
}
}
結果:
CGlib動態代理
目標類:
public class RealWork {
//新增
public void insertInf() {
System.out.println("增加...");
}
//刪除
public void deleteInf() {
System.out.println("刪除...");
}
//修改
public void updateInf() {
System.out.println("修改...");
}
//查詢
public void selectInf() {
System.out.println("查詢...");
}
}
代理工廠:
public class ProxyFactory {
// 被代理對象
private Object object;
public ProxyFactory(Object object) {
this.object = object;
}
public Enhancer getProxyInstance(){
//創建cglib核心對象
Enhancer enhancer = new Enhancer();
//設置父類
enhancer.setSuperclass(object.getClass());
//設置回調
enhancer.setCallback(new org.springframework.cglib.proxy.MethodInterceptor() {
/**
* 當你調用目標方法時,實質上是調用該方法
* intercept四個參數:
* proxy:代理對象
* method:目標方法
* args:目標方法的形參
* methodProxy:代理方法
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// TODO Auto-generated method stub
//在代理真實對象前我們可以添加一些自己的操作
System.out.println("調用方法前執行!");
//目標方法調用
Object result = methodProxy.invokeSuper(proxy, args);
System.out.println("方法執行完畢!");
return result;
}
});
return enhancer;
}
}
測試:
public class Test {
public static void main(String[] args) {
RealWork realWork = new RealWork();
//創建代理對象
RealWork proxyObj = (RealWork) new ProxyFactory(realWork).getProxyInstance().create();
proxyObj.insertInf();
proxyObj.deleteInf();
proxyObj.updateInf();
proxyObj.deleteInf();
}
}
結果: