手动使用cglib代理(了解)
生活随笔
收集整理的這篇文章主要介紹了
手动使用cglib代理(了解)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
這個你學(xué)會了將來也沒啥機(jī)會用,將來你要玩AOP,學(xué)會了也只是得瑟一下說來手寫一個AOP,你看看我是否厲害,你不明白太陽是7個顏色構(gòu)成的,也不影響你曬太陽,然后呢,AOP這個代碼呢,咱們再來一個UserServiceProxyFactory2,剛才在這里面的話,這叫觀光代碼,之動態(tài)代理,咱們這個2呢,更是觀光代碼了,之cglib代理,接下來看一下,這個代理類當(dāng)中,方法都一樣的,也是一個獲得UserService代理對象的方法,然后只是咱們用cglib代理來做,cglib作為第三方代理的話,理論上是要導(dǎo)包的,但是因為咱們的Spring,整合了cglib代理,所以cglib包,已經(jīng)在Spring包中了,這里直接寫一個,叫做Enhancer,cglib玩的話,核心叫做Enhancer,直接new就可以了,然后Enhancer拿出來以后,接下來的話你得告訴他,這哥們是給你產(chǎn)生代理對象的,幫我們生成代理對象的,那你拿著這個類,你得告訴他,你得告訴他目標(biāo)對象是誰啊,setSuperClass,告訴他目標(biāo)對象是誰,人家要你給的是一個class,咱們說了,cglib主要是對類進(jìn)行繼承代理,所以你得告訴他爹是誰,那要對誰進(jìn)行代理啊,對UserService進(jìn)行代理,UserServiceImpl這個是代理的對象,是不是這個意思,然后en.setCallback,這個生成代理你想干啥,這個是設(shè)置對誰進(jìn)行代理,下面是代理要做什么,這個cglib是這個玩法,咱們實現(xiàn)Callback,咱們找一下是哪一個Callback,這個Callback看一下,找到子類MethodInterceptor,然后這個東西是Callback接口的子類,發(fā)現(xiàn)子類太多了,然后他在這里面?zhèn)髁怂膫€參數(shù),這四個參數(shù),這個是arg,這是被代理的方法method,原始的方法,這是被代理的對象obj,目的跟之前一樣,首先要調(diào)用原有的方法,在原有方法執(zhí)行之前打開事務(wù),調(diào)用原有方法之后,提交事務(wù),然后這個返回值,然后接下來的話咱們看一下,用原有的方法怎么來調(diào),原有的方法可以使用MethodProxy,點invokeProxy,這東西沒啥道理,然后方法的參數(shù)就是他,把這個參數(shù)拿過來,然后前面要給他一個對象,這個對象的話我看看,proxyObj,把這個返回值接收一下,然后這個叫returnValue吧,然后把這個返回,這樣的話原有的方法就調(diào)用了,接下來打開事務(wù)這塊,打印一下打印事務(wù),然后提交事務(wù)這塊打印一下提交事務(wù),然后en點create方法,這個叫創(chuàng)建代理對象,然后接收一下,UserService接收,這個代理對象不就是UserService接口的子類嗎,然后return us,這樣的話就返回代理對象
package com.learn.c_proxy;import java.lang.reflect.Method;import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import com.learn.service.UserService;
import com.learn.service.UserServiceImpl;/*** 觀光代碼=>cglib代理* @author Leon.Sun**/
public class UserServiceProxyFactory2 implements MethodInterceptor {public UserService getUserServiceProxy() {/*** 幫我們生成代理對象*/Enhancer en = new Enhancer();/*** 設(shè)置對誰進(jìn)行代理*/en.setSuperclass(UserServiceImpl.class);/*** 代理要做什么*/en.setCallback(this);/*** 創(chuàng)建代理對象*/UserService us = (UserService) en.create();return us;}@Overridepublic Object intercept(Object proxyObj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {/*** 打開事務(wù)*/System.out.println("打印事務(wù)!");/*** 調(diào)用原有方法*/Object returnValue = methodProxy.invokeSuper(proxyObj, arg);/*** 提交事務(wù)*/System.out.println("提交事務(wù)!");return returnValue;}
}
咱們就是new一個UserServiceProxyFactory2,然后這個參數(shù),然后這塊的話是2,調(diào)回方法,返回代理對象,執(zhí)行一下看行不行
@Testpublic void fun2() {UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();UserService usProxy = factory.getUserServiceProxy();usProxy.save();}
打印事務(wù)!
保存用戶!
提交事務(wù)!
所以你看看,咱們使用cglib代理,也是生成代理對象,為我們的目標(biāo)方法進(jìn)行一個增強(qiáng),之前打開事務(wù),之后提交事務(wù),然后接下來你得再看一下,咱們生成的UserProxy對象,給你們看看原理,生成proxy對象,instanceof,判斷他是不是UserServiceImpl類型的,能看到是啥意思不,這個是判斷代理對象,是否是被代理對象類型,咱們說這個cglib的特點,代理對象繼承了被代理對象,所以這個代理對象實際上是,代理對象實際上被代理對象的子類,那你子類判斷是否屬于父類,那是true還是false,所以執(zhí)行的話是true
@Testpublic void fun2() {UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();UserService usProxy = factory.getUserServiceProxy();usProxy.save();/*** 判斷代理對象是否屬于被代理對象類型*/System.out.println(usProxy instanceof UserServiceImpl);}
打印事務(wù)!
保存用戶!
提交事務(wù)!
true
通過這個打印就說明了,咱們的代理對象繼承了被代理對象,所以結(jié)果是true,然后再看,這個實現(xiàn)可以拿到上面來做一個,上面咱們這個是動態(tài)代理的,動態(tài)代理中代理對象和被代理對象之間有什么關(guān)系,有什么關(guān)系,他們之間的關(guān)系,其實說實話,沒關(guān)系,他們其實僅僅是實現(xiàn)了同一個接口,所以這個判斷結(jié)果是什么,是false,看到效果了嗎
/*** 動態(tài)代理*/@Testpublic void fun1() {UserService us = new UserServiceImpl();UserServiceProxyFactory factory = new UserServiceProxyFactory(us);UserService usProxy = factory.getUserServiceProxy();usProxy.save();/*** false*/System.out.println(usProxy instanceof UserServiceImpl);}
打開事務(wù)
保存用戶!
提交事務(wù)
false
是代理對象和被代理對象實現(xiàn)了相同的接口,所以代理對象和被代理對象之間,你要是說有關(guān)系,那也是兄弟的關(guān)系,同一個爹,實現(xiàn)相同的接口,這個代理對象和被代理對象,沒有這個繼承關(guān)系,看明白啥意思吧,這個知識點要你們掌握的,這個叫觀光代碼,要求你們掌握的是,知道這兩種代理他們的特點,動態(tài)代理是接口,而cglib是對被代理對象進(jìn)行繼承,這是你們要知道的概念
?
總結(jié)
以上是生活随笔為你收集整理的手动使用cglib代理(了解)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: aop实现原理-动态代理CGLib代理
- 下一篇: spring的aop名词解释