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