動態(tài)代理系列(四)RPC中動態(tài)代理

看過上一講動態(tài)代理換種玩法咬荷,我們知道通過變形的動態(tài)代理膛薛,可以不需要目標(biāo)類刽射,就能生成代理類。

這種技術(shù)剃执,在我們今天的RPC框架中可以說被廣泛的使用誓禁。


RPC調(diào)用.jpg

下面我就通過我寫的一個簡單的RPC組件 來介紹它是如何實現(xiàn)。(注意:當(dāng)前版本可能為快照版本肾档,代碼在dev分支摹恰,未合并到master分支)

Spring的Autowired裝配

在Spring中,我們可以通過Autowired方式進行對象的裝配注入怒见,也就是說字段要被注入俗慈,需要被注解標(biāo)記。那么我們可以猜想遣耍,Spring一定有一段邏輯闺阱,來操作這個注入裝配的過程。

并且舵变,Spring為了好的可擴展性酣溃,以插件化的方式對裝配Bean的過程進行補充,這些插件就叫后處理器纪隙。而對Autowired進行組裝的后處理器就是:AutowiredAnnotationBeanPostProcessor赊豌,而具體的實現(xiàn)方法就是postProcessPropertyValues()。有興趣的可以自行閱讀绵咱。

RPC調(diào)用

我們知道本地調(diào)用肯定是通過對象完成碘饼,僅僅接口,如果沒有實例對象悲伶,是要報空指針的艾恼,但是RPC是遠(yuǎn)程的過程調(diào)用,是調(diào)用遠(yuǎn)程的對象麸锉,遠(yuǎn)程的方法蒂萎,本地是沒有實例對象存在的,那不就矛盾了嗎淮椰?

毫無疑問五慈,調(diào)用纳寂,肯定就有對象,只不過泻拦,這個對象我們沒有手工編碼毙芜,看到這里,可能有些同學(xué)已經(jīng)想到什么了争拐。沒錯腋粥,就是上節(jié)介紹的動態(tài)代理為接口偽裝出一個實現(xiàn)類。

對象可以通過動態(tài)代理生成架曹,那么如何把生成的對象如同Autowired注解標(biāo)記的字段一樣進行裝配呢隘冲?

實現(xiàn)裝配

既然我們知道了Autowired注解裝配的原理—通過后處理器完成。那么最簡單的方式绑雄,我們就仿照寫一個注解展辞,一個處理器不就成了。

注解

我們寫的注解是Reference万牺,在SpringBean中被使用罗珍,看下面代碼:

@RestController
public class DemoController {
    
    @Reference(contract = IntfDemo.class, implCode = "abc")
    private IntfDemo intfDemo;

    @RequestMapping(path = "f1")
    public String f1() {
        return intfDemo.name();
    }
}

裝配處理器

寫一個后處理,來處理被Reference注解標(biāo)記的字段脚粟,具體實現(xiàn)如下:

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;

/**
 * 處理SpringBean的{@link Reference} 屬性的注入
 *
 * @author: guanjie
 */
@Component
@Slf4j
public class ReferenceBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {


    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, final Object bean, final String beanName) throws BeansException {
        ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {
            @Override
            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                FieldUtils.writeField(field, bean, ServerProxy.getProxy(field), true);
            }
        }, new ReflectionUtils.FieldFilter() {
            @Override
            public boolean matches(Field field) {
                return field.isAnnotationPresent(Reference.class);
            }
        });
        return pvs;
    }
}

看上面功能代碼覆旱,不超過20行,就把這個功能完成了核无,而Spring會自動發(fā)現(xiàn)這個處理器扣唱,并在裝配階段對每個Bean使用。
ServerProxy.getProxy(field)和上節(jié)中生成代理類的方式幾乎一樣团南,只不過把處理邏輯換成了IO通信而已画舌。

原理懂了其實還是挺簡單的,想了解的更多已慢,可以拉下代碼研究曲聂,歡迎感興趣的同學(xué)一起來進行代碼的維護和后續(xù)的補充。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末佑惠,一起剝皮案震驚了整個濱河市朋腋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌膜楷,老刑警劉巖旭咽,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異赌厅,居然都是意外死亡穷绵,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門特愿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仲墨,“玉大人勾缭,你說我怎么就攤上這事∧垦” “怎么了俩由?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長癌蚁。 經(jīng)常有香客問我幻梯,道長,這世上最難降的妖魔是什么努释? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任碘梢,我火速辦了婚禮,結(jié)果婚禮上伐蒂,老公的妹妹穿的比我還像新娘煞躬。我一直安慰自己,他們只是感情好饿自,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布汰翠。 她就那樣靜靜地躺著龄坪,像睡著了一般昭雌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上健田,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天烛卧,我揣著相機與錄音,去河邊找鬼妓局。 笑死总放,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的好爬。 我是一名探鬼主播局雄,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼存炮!你這毒婦竟也來了炬搭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤穆桂,失蹤者是張志新(化名)和其女友劉穎宫盔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體享完,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡灼芭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了般又。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片彼绷。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡巍佑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出苛预,到底是詐尸還是另有隱情句狼,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布热某,位于F島的核電站腻菇,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏昔馋。R本人自食惡果不足惜筹吐,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秘遏。 院中可真熱鬧丘薛,春花似錦、人聲如沸邦危。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽倦蚪。三九已至希坚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陵且,已是汗流浹背裁僧。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留慕购,地道東北人聊疲。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像沪悲,于是被迫代替她去往敵國和親获洲。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容