final类是否可以被代理_设计模式——代理模式
代理模式
什么是代理模式
通過代理控制對(duì)象的訪問,可以詳細(xì)訪問某個(gè)對(duì)象的方法,在這個(gè)方法調(diào)用處理,或調(diào)用后處理。既(AOP微實(shí)現(xiàn)) ,AOP核心技術(shù)面向切面編程。
代理模式應(yīng)用場(chǎng)景
SpringAOP、事物原理、日志打印、權(quán)限控制、遠(yuǎn)程調(diào)用、安全代理 可以隱蔽真實(shí)角色
代理的分類
- 動(dòng)態(tài)代理(動(dòng)態(tài)生成代理類)
- Jdk自帶動(dòng)態(tài)代理
- Cglib 、javaassist(字節(jié)碼操作庫)
靜態(tài)代理
什么是靜態(tài)代理
由程序員創(chuàng)建或根據(jù)生成的代理類源碼,再變異代理類。所謂靜態(tài)也就是在程序運(yùn)行前就已經(jīng)存在代理類的字節(jié)碼文件,代理類和委托類的關(guān)系在運(yùn)行前就確定類
interface IUserDao{ void save(); }/** * 接口實(shí)現(xiàn)類 */public class UserDaoImpl implements IUserDao{ @Override public void save() { System.out.println("已經(jīng)保存數(shù)據(jù)..."); }}/** * 代理類 */class UserDaoProxy implements IUserDao{ private IUserDao userDao; public UserDaoProxy(IUserDao userDao) { this.userDao = userDao; } @Override public void save() { System.out.println("開啟事物..."); userDao.save(); System.out.println("關(guān)閉事物..."); } }public static void main(String[] args) { IUserDao userDao = new UserDaoImpl(); UserDaoProxy userDaoProxy = new UserDaoProxy(userDao); userDaoProxy.save(); }動(dòng)態(tài)代理
什么是動(dòng)態(tài)代理
**1.代理對(duì)象,不需要實(shí)現(xiàn)接口
2.代理對(duì)象的生成,是利用JDK的API,動(dòng)態(tài)的在內(nèi)存中構(gòu)建代理對(duì)象(需要我們指定創(chuàng)建代理對(duì)象/目標(biāo)對(duì)象實(shí)現(xiàn)的接口的類型)
3.動(dòng)態(tài)代理也叫做:JDK代理,接口代理**
JDK動(dòng)態(tài)代理
原理:是根據(jù)類加載器和接口創(chuàng)建代理類(此代理類是接口的實(shí)現(xiàn)類,所以必須使用接口面向接口生成代理,位于java.lang.reflect包下) 2)實(shí)現(xiàn)方式:通過實(shí)現(xiàn)InvocationHandler接口創(chuàng)建自己的調(diào)用處理器 IvocationHandler handler = new InvocationHandlerImpl(…);通過為Proxy類指定ClassLoader對(duì)象和一組interface創(chuàng)建動(dòng)態(tài)代理類Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});通過反射機(jī)制獲取動(dòng)態(tài)代理類的構(gòu)造函數(shù),其參數(shù)類型是調(diào)用處理器接口類型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});通過構(gòu)造函數(shù)創(chuàng)建代理類實(shí)例,此時(shí)需將調(diào)用處理器對(duì)象作為參數(shù)被傳入Interface Proxy = (Interface)constructor.newInstance(new Object[](handler));
缺點(diǎn):jdk動(dòng)態(tài)代理,必須是面向接口,目標(biāo)業(yè)務(wù)類必須實(shí)現(xiàn)接口
/** * JDK動(dòng)態(tài)代理 */public class InvocationHandlerImpl implements InvocationHandler { // 每次生成動(dòng)態(tài)代理類對(duì)象時(shí),實(shí)現(xiàn)了InvocationHandler接口的調(diào)用處理器對(duì)象 // 這其實(shí)業(yè)務(wù)實(shí)現(xiàn)類對(duì)象,用來調(diào)用具體的業(yè)務(wù)方法 private Object target; public InvocationHandlerImpl(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("動(dòng)態(tài)代理 -- 開啟事物"); result = method.invoke(target, args); System.out.println("動(dòng)態(tài)代理 -- 提交事物"); return result; }}interface IUserDao{ void save();}/** * 接口實(shí)現(xiàn)類 */class UserDaoImpl implements IUserDao{ @Override public void save() { System.out.println("已經(jīng)保存數(shù)據(jù)..."); }}public static void main(String[] args) { IUserDao userDao = new UserDaoImpl(); InvocationHandlerImpl invocationHandler = new InvocationHandlerImpl(userDao); ClassLoader classLoader = userDao.getClass().getClassLoader(); Class>[] interfaces = userDao.getClass().getInterfaces(); IUserDao newUserDao= (IUserDao)Proxy.newProxyInstance(classLoader, interfaces, invocationHandler); newUserDao.save(); }CGLIB動(dòng)態(tài)代理
- 原理: 利用asm 開源包,對(duì)代理對(duì)象類的class 文件加載進(jìn)來,通過修改其字節(jié)碼生成子類來處理。
什么是CGLIB動(dòng)態(tài)代理
- 使用cglib[Code Generation Library]實(shí)現(xiàn)動(dòng)態(tài)代理,并不要求委托類必須實(shí)現(xiàn)接口,底層采用asm字節(jié)碼生成框架生成代理類的字節(jié)碼
CGLIB動(dòng)態(tài)代理與JDK動(dòng)態(tài)區(qū)別
java動(dòng)態(tài)代理是利用反射機(jī)制生成一個(gè)實(shí)現(xiàn)代理接口的匿名類,在調(diào)用具體方法前調(diào)用InvokeHandler來處理, 而 cglib 動(dòng)態(tài)代理是利用 asm 開源包,對(duì)代理對(duì)象類對(duì)class文件加載進(jìn)來,通過修改其字節(jié)碼生成子類來處理。
Spring中:
CGLIB是針對(duì)類實(shí)現(xiàn)代理,主要是對(duì)指定對(duì)類生成一個(gè)子類,覆蓋其中對(duì)方法
因?yàn)槭抢^承,所以該類或方法最好不要聲明成final,final可以阻止繼承和多態(tài)
文章鏈接:https://developer.aliyun.com/article/780194
總結(jié)
以上是生活随笔為你收集整理的final类是否可以被代理_设计模式——代理模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: python io多路复用_Python
- 下一篇: python 整合excel_pytho
