zbb20180930 代理模式 -靜態代理-jdk動態代理-cglib動態代理
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 private XiaoMing xiaoMing; public Proxy(XiaoMing xiaoMing) { this.xiaoMing = xiaoMing; } public void mai() { System.out.println("我是中介 看你買房開始啦!"); xiaoMing.mai(); System.out.println("我是中介 看你買房結束啦!"); } public static 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動態代理