前提:代理類和被代理類均繼承自統一接口。代理模式是使用代理類去控制被代理類的方法。(ps:好久沒更新,不知道更啥,先發着以前寫的。。。)
設計模式之代理模式
靜態代理、JDK動態代理、Cglib動態代理區別(面試題):
靜態代理需要目標對象、代理對象均實現同一接口。JDK動態代理僅需目標對象實現接口。Cglib動態代理中目標對象、代理對象均不用實現接口,其底層通過ASM轉換字節碼來生成目標對象子類,從而實現對目標對象的功能擴展。Aop也是根據目標對象是否有接口來決定用JDK還是Cglib動態代理。
--------------------------------靜態代理----------------------------------------
1 公用接口類(買房方式):
public interface BuyHouse {
void buyHosue();
}
2 被代理類類(買房的人-自己找):
public class BuyHouseImpl implements BuyHouse {
@Override
public void buyHosue() {
System.out.println("我要買房");
}
}
3 代理類(中介-中介找):
public class BuyHouseProxy implements BuyHouse {
private BuyHouse buyHouse;
public BuyHouseProxy(final BuyHouse buyHouse) {
this.buyHouse = buyHouse;
}
@Override
public void buyHosue() {
System.out.println("買房前準備");
buyHouse.buyHosue();
System.out.println("買房後裝修");
}
}
4 調用:
public class Test {
public static void main(String[] args) {
BuyHouse buyHouseProxy = new BuyHouseProxy(new BuyHouseImpl());
buyHouseProxy.buyHosue(); //結果:“買房前準備 我要買房 買房後裝修”
}
}
--------------------------------靜態代理----------------------------------------
--------------------------------JDK動態代理----------------------------------------
/** * 創建動態代理對象
* 動態代理不需要實現接口,但是需要指定接口類型
*/
public class ProxyFactory{
//維護一個目標對象
private Object target;
public ProxyFactory(Object target){ this.target=target; }
//給目標對象生成代理對象
public Object getProxyInstance(){
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("開始事務2");
//執行目標對象方法 Object returnValue = method.invoke(target, args);
System.out.println("提交事務2");
return returnValue;
}
}
);
}
}
public class App {
public static void main(String[] args) {
// 目標對象
IUserDao target = new UserDao();
// 【原始的類型 class cn.itcast.b_dynamic.UserDao】
System.out.println(target.getClass());
// 給目標對象,創建代理對象
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
// class $Proxy0 內存中動態生成的代理對象
System.out.println(proxy.getClass());
// 執行方法 【代理對象】
proxy.save();
}
}
--------------------------------Cglib動態代理----------------------------------------
/** * Cglib子類代理工廠 * 對UserDao在內存中動態構建一個子類對象 */
public class ProxyFactory implements MethodInterceptor{
//維護目標對象
private Object target;
public ProxyFactory(Object target) { this.target = target; }
//給目標對象創建一個代理對象
public Object getProxyInstance(){
//1.工具類
Enhancer en = new Enhancer();
//2.設置父類
en.setSuperclass(target.getClass());
//3.設置回調函數
en.setCallback(this);
//4.創建子類(代理對象)
return en.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
throws Throwable {
System.out.println("開始事務...");
//執行目標對象的方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事務...");
return returnValue;
}
}
--------------------------------Cglib動態代理----------------------------------------
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.