您好,登錄后才能下訂單哦!
這篇文章主要介紹“MyBatis反射和動(dòng)態(tài)代理的定義”,在日常操作中,相信很多人在MyBatis反射和動(dòng)態(tài)代理的定義問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”MyBatis反射和動(dòng)態(tài)代理的定義”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
首先看看官網(wǎng)對(duì)反射的定義:
可以通過(guò)java代碼,獲取當(dāng)前加載類的字段、方法、構(gòu)造函數(shù)等信息,并在安全限制內(nèi),使用反射字段、方法、構(gòu)造函數(shù)進(jìn)行操作。
簡(jiǎn)單來(lái)說(shuō),可以在運(yùn)行時(shí)獲得程序中每一個(gè)類型的成員信息。程序中定義的對(duì)象,其類型都是在編譯期確定的,而反射可以動(dòng)態(tài)地創(chuàng)建對(duì)象,并訪問(wèn)或調(diào)用其成員。
所謂代理,是一個(gè)人或組織代替另一個(gè)人或組織做事,主要有3個(gè)角色:訪問(wèn)者、代理人、被代理人,訪問(wèn)者經(jīng)由代理人,與被代理人交互,中間會(huì)加入一些自己的處理。
所謂的動(dòng)態(tài)代理,是說(shuō)在編譯時(shí)不需要定義代理類,而是在運(yùn)行時(shí)創(chuàng)建,這個(gè)是關(guān)鍵:在運(yùn)行時(shí)創(chuàng)建代理類。
Class類是一個(gè)實(shí)實(shí)在在的類,存在于java.lang包中,用來(lái)表示運(yùn)行時(shí)類型信息。Class對(duì)象表示自定義類的類型信息,比如創(chuàng)建一個(gè)User類,JVM就會(huì)創(chuàng)建一個(gè)User對(duì)應(yīng)的Class對(duì)象,保存User類相關(guān)的類型信息,該對(duì)象保存在jvm堆中,作為訪問(wèn)方法區(qū)中User類型信息的接口。
在使用自定義類時(shí),會(huì)首先檢查這個(gè)類的Class對(duì)象是否已經(jīng)加載,如果沒有加載,默認(rèn)的類加載器就會(huì)先根據(jù)類名查找.class文件,Class對(duì)象就會(huì)被加載到內(nèi)存。
可以通過(guò)下面3種方法獲取Class對(duì)象:
使用Class類的forName靜態(tài)方法;
直接獲取某一個(gè)對(duì)象的class;
調(diào)用某個(gè)對(duì)象的getClass()方法;
Class對(duì)象是反射的基礎(chǔ),提供了獲取類信息的方法,后面會(huì)介紹。
java反射框架主要提供以下內(nèi)容:
在運(yùn)行時(shí)判斷對(duì)象所屬的類;
在運(yùn)行時(shí)創(chuàng)建對(duì)象;
在運(yùn)行時(shí)獲取類包含的成員變量、方法、父類、接口等信息;
在運(yùn)行時(shí)調(diào)用一個(gè)對(duì)象的方法;
下面舉例說(shuō)明相關(guān)功能
創(chuàng)建實(shí)例:
//獲取String所對(duì)應(yīng)的Class對(duì)象 Class<?> c = User.class; //獲取String類帶一個(gè)String參數(shù)的構(gòu)造器 Constructor constructor = c.getConstructor(String.class); //根據(jù)構(gòu)造器創(chuàng)建實(shí)例 User user = (User)constructor.newInstance("calm");
獲取方法:
//返回類或接口聲明的所有方法,包括私有的,但不包括繼承的方法 public Method[] getDeclaredMethods() throws SecurityException //所有public方法,包括繼承的方法 public Method[] getMethods() throws SecurityException //返回一個(gè)特定的方法,第一個(gè)參數(shù)為方法名稱,后面的參數(shù)為方法參數(shù)對(duì)應(yīng)Class的對(duì)象 public Method getMethod(String name, Class<?>... parameterTypes)
調(diào)用方法:
Class<?> userClass=User.class; Object obj = userClass.newInstance(); Method method =klass.getMethod("addRole",String.class); method.invoke(obj,"超級(jí)管理員");
JDK本身提供了動(dòng)態(tài)代理的實(shí)現(xiàn),要求被代理者必須實(shí)現(xiàn)接口。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)
第一個(gè)參數(shù)為類加載器,第二個(gè)參數(shù)是被代理者實(shí)現(xiàn)的接口列表,第三個(gè)參數(shù)是實(shí)現(xiàn)了InvocationHandler接口的對(duì)象。
InvocationHandler是一個(gè)接口,用于規(guī)范執(zhí)行被代理者的方法,可在執(zhí)行方法前后,添加公共的處理代碼。生成的動(dòng)態(tài)代理類包含一個(gè)InvocationHandler屬性,調(diào)用對(duì)應(yīng)方法時(shí),會(huì)觸發(fā)invoke方法的調(diào)用。
public class JDKProxy implements InvocationHandler { private Object targetObject;//被代理對(duì)象 public Object newProxy(Object targetObject) { this.targetObject = targetObject; return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args)//invoke方法 throws Throwable { Object ret = null; ret = method.invoke(targetObject, args); return ret; } }
測(cè)試代碼:
JDKProxy jdkProxy=new JDKProxy(); UserService userService = (UserService) jdkProxy.newProxy(new UserServiceImp()); userService.addRole("超級(jí)管理員");
JDK動(dòng)態(tài)代理的基本原理是根據(jù)定義好的規(guī)則,用傳入的接口創(chuàng)建一個(gè)新類。
JDK動(dòng)態(tài)代理要求必須有接口,CGLIB(Code Generate Library)動(dòng)態(tài)代理沒有這個(gè)要求,它是通過(guò)創(chuàng)建一個(gè)被代理類的子類,然后使用ASM字節(jié)碼庫(kù)修改代碼來(lái)實(shí)現(xiàn)的。
public class CGLibProxy implements MethodInterceptor { private Object targetObject; //被代理對(duì)象 public Object createProxyObject(Object obj) { this.targetObject = obj; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(obj.getClass()); enhancer.setCallback(this); Object proxyObj = enhancer.create(); return proxyObj; } public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object obj = null; obj = method.invoke(targetObject, args); return obj; } }
測(cè)試代碼:
CGLibProxy cgLibProxy=new CGLibProxy(); UserService userService = (UserService) cgLibProxy.newProxy(new UserServiceImp()); userService.addRole("超級(jí)管理員");
到此,關(guān)于“MyBatis反射和動(dòng)態(tài)代理的定義”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。