1. 程式人生 > >zbb20180930 代理模式 -靜態代理-jdk動態代理-cglib動態代理

zbb20180930 代理模式 -靜態代理-jdk動態代理-cglib動態代理

auth 動態代理 bsp 遠程 開始 pan 後處理 reflect tcl

CGLIB與JDK動態代理區別

區別:
java動態代理是利用反射機制生成一個實現代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理。而cglib動態代理是利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理。
1、如果目標對象實現了接口,默認情況下會采用JDK的動態代理實現AOP
2、如果目標對象實現了接口,可以強制使用CGLIB實現AOP
3、如果目標對象沒有實現了接口,必須采用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換

代理模式

什麽是代理?

通過代理控制對象的訪問,可以詳細訪問某個對象的方法,在這個方法調用處理,或調用後處理。既(AOP微實現) ,AOP核心技術面向切面編程。

技術分享圖片

代理應用場景

安全代理 可以屏蔽真實角色

遠程代理 遠程調用代理類RMI

延遲加載 先加載輕量級代理類,真正需要在加載真實

代理的分類

靜態代理(靜態定義代理類)

動態代理(動態生成代理類)

Jdk自帶動態代理

Cglib 、javaassist(字節碼操作庫)

靜態代理

靜態代理需要自己生成代理類

public class XiaoMing implements Hose {

@Override

public void mai() {

System.out.println("我是小明,我要買房啦!!!!haha ");

}

}

class

Proxy implements Hose {

private XiaoMing xiaoMing;

public Proxy(XiaoMing xiaoMing) {

this.xiaoMing = xiaoMing;

}

public void mai() {

System.out.println("我是中介 看你買房開始啦!");

xiaoMing.mai();

System.out.println("我是中介 看你買房結束啦!");

}

public static

void main(String[] args) {

Hose proxy = new Proxy(new XiaoMing());

proxy.mai();

}

}

JDK動態代理(不需要生成代理類)

實現InvocationHandler 就可以了。

public interface Hose {

/**

*

* @methodDesc: 功能描述:(買房代理)

* @author: 余勝軍

* @param:

* @createTime:2017年8月27日 上午2:54:34

* @returnType: void

* @copyright:上海每特教育科技有限公司

*/

public void mai();

}

public class XiaoMing implements Hose {

@Override

public void mai() {

System.out.println("我是小明,我要買房啦!!!!haha ");

}

}

public class JDKProxy implements InvocationHandler {

private Object tarjet;

public JDKProxy(Object tarjet) {

this.tarjet = tarjet;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

System.out.println("我是房產中介.....開始監聽你買房啦!");

Object oj = method.invoke(tarjet, args);

System.out.println("我是房產中介.....結束監聽你買房啦!");

return oj;

}

}

class Test222 {

public static void main(String[] args) {

XiaoMing xiaoMing = new XiaoMing();

JDKProxy jdkProxy = new JDKProxy(xiaoMing);

Hose hose=(Hose) Proxy.newProxyInstance(xiaoMing.getClass().getClassLoader(), xiaoMing.getClass().getInterfaces(), jdkProxy);

hose.mai();

}

}

CGLIB動態代理

實現

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

public class Cglib implements MethodInterceptor {

@Override

public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

System.out.println("我是買房中介 開始監聽你買房了....");

Object invokeSuper = methodProxy.invokeSuper(o, args);

System.out.println("我是買房中介 開結束你買房了....");

return invokeSuper;

}

}

class Test22222 {

public static void main(String[] args) {

Cglib cglib = new Cglib();

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(XiaoMing.class);

enhancer.setCallback(cglib);

Hose hose = (Hose) enhancer.create();

hose.mai();

}

}

CGLIB與JDK動態代理區別

區別:
java動態代理是利用反射機制生成一個實現代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理。而cglib動態代理是利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理。
1、如果目標對象實現了接口,默認情況下會采用JDK的動態代理實現AOP
2、如果目標對象實現了接口,可以強制使用CGLIB實現AOP
3、如果目標對象沒有實現了接口,必須采用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換

zbb20180930 代理模式 -靜態代理-jdk動態代理-cglib動態代理