成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

dubbo擴(kuò)展點(diǎn)的IOC

Zoom / 3228人閱讀

摘要:屬性上篇文章中,提到在獲取擴(kuò)展點(diǎn)接口對(duì)應(yīng)的的時(shí)候,會(huì)執(zhí)行私有構(gòu)造函數(shù)。因?yàn)榇藭r(shí)是,即當(dāng)為時(shí),即我們可以看出,所有非擴(kuò)展點(diǎn)接口都會(huì)執(zhí)行對(duì)應(yīng)的實(shí)例的方法返回一個(gè)實(shí)例,即對(duì)象。

spring是如何獲得容器中管理的類的

拿到applicationContext,就可以調(diào)用getBean方法來(lái)獲得Spring的bean對(duì)象了

public class SpringContextUtil implements ApplicationContextAware {  
    // Spring應(yīng)用上下文環(huán)境  
    private static ApplicationContext applicationContext;  
    /** 
     * 實(shí)現(xiàn)ApplicationContextAware接口的回調(diào)方法,設(shè)置上下文環(huán)境 
     *  
     * @param applicationContext 
     */  
    public void setApplicationContext(ApplicationContext applicationContext) {  
        SpringContextUtil.applicationContext = applicationContext;  
    }  
    /** 
     * @return ApplicationContext 
     */  
    public static ApplicationContext getApplicationContext() {  
        return applicationContext;  
    }  
    /** 
     * 獲取對(duì)象 
     *  
     * @param name 
     * @return Object
     * @throws BeansException 
     */  
    public static Object getBean(String name) throws BeansException {  
        return applicationContext.getBean(name);  
    }  
}
dubbo擴(kuò)展點(diǎn)的IOC 前文中,大致有提到一些有關(guān)IOC

第一點(diǎn) 在講解ExtensionLoader源碼的構(gòu)造函數(shù)的時(shí)候,我們說(shuō)過(guò),每一個(gè)ExtensionLoader實(shí)例都有一個(gè) objectFactory 屬性,他是實(shí)現(xiàn)Ioc的關(guān)鍵;

第二點(diǎn) 相比較于JDK的SPI機(jī)制,dubbo的SPI機(jī)制支持?jǐn)U展通過(guò)setter的方式來(lái)注入其他擴(kuò)展點(diǎn)。

第三點(diǎn) 在調(diào)用ExtensionLoader的getExtension方法時(shí),在獲取了相應(yīng)的class并創(chuàng)建了instance之后,通過(guò)injectExtension(intance)方法來(lái)通過(guò)setter的方式來(lái)注入其他擴(kuò)展點(diǎn)。

第四點(diǎn) loadFile函數(shù)解析SPI配置時(shí),假如這個(gè)類帶@Adaptive注解,緩存到cachedAdaptiveClass。

如何實(shí)現(xiàn)IOC -> ExtensionLoader的injectExtension方法源碼

關(guān)鍵說(shuō)明,

獲取instance的所有方法,并解析以set方法開(kāi)頭的方法,例如setXxyy(Xxyy xxyy)。

拿到set方法的入?yún)㈩愋蚗xyy、屬性名xxyy。

執(zhí)行objectFactory.getExtension(pt, property)拿到Xxyy對(duì)應(yīng)的實(shí)例。

通過(guò)反射執(zhí)行set方法,注入Xxyy對(duì)象。

    private T injectExtension(T instance) {
        try {
            if (objectFactory != null) {
                for (Method method : instance.getClass().getMethods()) {
                    if (method.getName().startsWith("set")
                            && method.getParameterTypes().length == 1
                            && Modifier.isPublic(method.getModifiers())) {
                        Class pt = method.getParameterTypes()[0];
                        try {
                            String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";
                            Object object = objectFactory.getExtension(pt, property);
                            if (object != null) {
                                method.invoke(instance, object);
                            }
                        } catch (Exception e) {
                            logger.error("fail to inject via method " + method.getName()
                                    + " of interface " + type.getName() + ": " + e.getMessage(), e);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return instance;
    }
通過(guò)上面的方法,就可以將屬性注入到instance中,實(shí)現(xiàn)自動(dòng)裝配(IOC)。下面我們來(lái)看一下 objectFactory.getExtension(pt, property)是如何工作的。
objectFactory屬性
上篇文章中,提到在獲取Container擴(kuò)展點(diǎn)接口對(duì)應(yīng)的ExtensionLoader的時(shí)候,會(huì)執(zhí)行私有ExtensionLoader構(gòu)造函數(shù)。
    private ExtensionLoader(Class type) {
        this.type = type;
        objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
    }
因?yàn)榇藭r(shí)type是Container.class,即objectFactory = ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension();
當(dāng)type為ExtensionFactory.class時(shí),即 objectFactory = null.
我們可以看出,所有非ExtensionFactory.class擴(kuò)展點(diǎn)接口都會(huì)執(zhí)行ExtensionFactory對(duì)應(yīng)的ExtensionLoader實(shí)例的getAdaptiveExtension()方法返回一個(gè)ExtensionFactory實(shí)例,即objectFactory對(duì)象。否則,objectFactory對(duì)象為null。
核心方法 -> ExtensionLoader的getAdaptiveExtension方法源碼

getAdaptiveExtension 獲取帶有Adaptive注解的擴(kuò)展實(shí)現(xiàn)類

createAdaptiveExtension()創(chuàng)建實(shí)例

injectExtension() 自動(dòng)注入IOC

getAdaptiveExtensionClass() ---執(zhí)行cachedAdaptiveClass對(duì)象的構(gòu)造函數(shù)

getExtensionClasses() ---解析所有的擴(kuò)展點(diǎn)實(shí)現(xiàn)

loadExtensionClasses() ---加載擴(kuò)展類

loadFile() --- 從固定的文件路徑,解析加載對(duì)應(yīng)的擴(kuò)展點(diǎn)實(shí)現(xiàn)【上一篇已經(jīng)說(shuō)過(guò),這個(gè)地方會(huì)加載幾種情形的擴(kuò)展實(shí)現(xiàn)類,包括拿到cachedAdaptiveClass對(duì)象】

返回cachedAdaptiveClass --- 返回loadFile()方法中構(gòu)造的cachedAdaptiveClass對(duì)象

執(zhí)行 cachedAdaptiveClass.newInstance() ---執(zhí)行AdaptiveExtensionFactory的構(gòu)造函數(shù)

ExtensionFactory的實(shí)現(xiàn)類AdaptiveExtensionFactory帶有Adaptive標(biāo)簽,另外兩個(gè)實(shí)現(xiàn)類SpiExtensionFactory、SpringExtensionFactory就是正常的實(shí)現(xiàn)類,也是我們見(jiàn)的最多的那種擴(kuò)展點(diǎn)實(shí)現(xiàn)類。

### AdaptiveExtensionFactory源碼
關(guān)鍵說(shuō)明,
1. factories屬性,所有的非@Adaptive類的ExtensionFactory實(shí)例的集合,以后所有與ExtensionFactory打交道的操作都交給AdaptiveExtensionFactory,
2. injectExtension方法中,調(diào)用的 Object object = objectFactory.getExtension(pt, property);分別調(diào)用SpiExtensionFactory、SpringExtensionFactory兩個(gè)實(shí)際的實(shí)現(xiàn)類。
/**
 * AdaptiveExtensionFactory
 *
 * @author william.liangf
 */
@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {

    //所有的非@Adaptive類的ExtensionFactory實(shí)例的集合
    private final List factories;

    //因?yàn)镋xtensionFactory對(duì)應(yīng)的ExtensionLoader實(shí)例中緩存字段已經(jīng)初始化好了,所以的ExtensionLoader的操作大都是從緩存中獲取的數(shù)據(jù)
    public AdaptiveExtensionFactory() {
        //從緩存的static變量EXTENSION_LOADERS中拿到ExtensionFactory對(duì)應(yīng)的ExtensionLoader實(shí)例
        ExtensionLoader loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class);
        List list = new ArrayList();
        //拿到loader中加載的普通的SPI擴(kuò)展接口實(shí)現(xiàn)類的名稱,spring與spi
        // adaptive=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
        // spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory
        for (String name : loader.getSupportedExtensions()) {
            //根據(jù)名稱創(chuàng)建對(duì)應(yīng)的ExtensionFactory實(shí)例
            list.add(loader.getExtension(name));
        }
        factories = Collections.unmodifiableList(list);
    }

    public  T getExtension(Class type, String name) {
        for (ExtensionFactory factory : factories) {
            T extension = factory.getExtension(type, name);
            if (extension != null) {
                return extension;
            }
        }
        return null;
    }

}
SpringExtensionFactory源碼
public class SpringExtensionFactory implements ExtensionFactory {

    private static final Set contexts = new ConcurrentHashSet();

    public static void addApplicationContext(ApplicationContext context) {
        contexts.add(context);
    }

    public static void removeApplicationContext(ApplicationContext context) {
        contexts.remove(context);
    }

    @SuppressWarnings("unchecked")
    public  T getExtension(Class type, String name) {
        for (ApplicationContext context : contexts) {
            if (context.containsBean(name)) {
                Object bean = context.getBean(name);
                if (type.isInstance(bean)) {
                    return (T) bean;
                }
            }
        }
        return null;
    }

}

是不是有一點(diǎn)熟悉的味道了啊,這也算是一個(gè)首尾呼應(yīng)吧~

這一篇到時(shí)很快就寫完了~ 下篇文章會(huì)講解擴(kuò)展點(diǎn)是如何實(shí)現(xiàn)AOP的。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69057.html

相關(guān)文章

  • Dubbo SPI機(jī)制和IOC

    摘要:要構(gòu)建自適應(yīng)實(shí)例,先要有自適應(yīng)的實(shí)現(xiàn)類,實(shí)現(xiàn)類有兩種方式一種通過(guò)配置文件,一種是通過(guò)是字節(jié)碼的方式動(dòng)態(tài)生成。 SPI機(jī)制 SPI,即(service provider interface)機(jī)制,有很多組件的實(shí)現(xiàn),如日志、數(shù)據(jù)庫(kù)訪問(wèn)等都是采用這樣的方式,一般通用組件為了提升可擴(kuò)展性,基于接口編程,將操作接口形成標(biāo)準(zhǔn)規(guī)范,但是可以開(kāi)放多種擴(kuò)展實(shí)現(xiàn),這種做法也符合開(kāi)閉設(shè)計(jì)原則,使組件具有可插...

    Scorpion 評(píng)論0 收藏0
  • 聊聊Dubbo - Dubbo擴(kuò)展機(jī)制實(shí)戰(zhàn)

    摘要:今天我想聊聊的另一個(gè)很棒的特性就是它的可擴(kuò)展性。的擴(kuò)展機(jī)制在的官網(wǎng)上,描述自己是一個(gè)高性能的框架。接下來(lái)的章節(jié)中我們會(huì)慢慢揭開(kāi)擴(kuò)展機(jī)制的神秘面紗。擴(kuò)展擴(kuò)展點(diǎn)的實(shí)現(xiàn)類。的定義在配置文件中可以看到文件中定義了個(gè)的擴(kuò)展實(shí)現(xiàn)。 摘要: 在Dubbo的官網(wǎng)上,Dubbo描述自己是一個(gè)高性能的RPC框架。今天我想聊聊Dubbo的另一個(gè)很棒的特性, 就是它的可擴(kuò)展性。 Dubbo的擴(kuò)展機(jī)制 在Dub...

    techstay 評(píng)論0 收藏0
  • dubbo擴(kuò)展點(diǎn)機(jī)制

    摘要:在中配置,以配置為例整個(gè),最先使用的地方從里面讀取這個(gè)配置使用接口的中獲取具體的實(shí)現(xiàn)類中有兩個(gè)值當(dāng)主線程被外部終止時(shí),會(huì)觸發(fā),執(zhí)行的與方法通知下面的鎖操作,主線程正常走完代碼,并最終停止。 spring是如何啟動(dòng)容器的 常見(jiàn)的一種在本地使用main方法啟動(dòng)spring的方法 public static void main(String[] args) throws Except...

    Rindia 評(píng)論0 收藏0
  • Dubbo Spi機(jī)制

    摘要:為了實(shí)現(xiàn)在模塊裝配的時(shí)候,不在模塊里寫死代碼,就需要一種服務(wù)發(fā)現(xiàn)機(jī)制。就提供了這樣一種機(jī)制為某個(gè)接口尋找服務(wù)實(shí)現(xiàn),有點(diǎn)類似思想,將裝配的控制權(quán)移到代碼之外。即接口文件的全類名。五示例遵循上述第一條第點(diǎn),這里為接口文件,其中和為兩個(gè)實(shí)現(xiàn)類。 一、Dubbo內(nèi)核 Dubbo內(nèi)核主要包含SPI、AOP、IOC、Compiler。 二、JDK的SPI 1.spi的設(shè)計(jì)目標(biāo): 面向?qū)ο蟮脑O(shè)計(jì)里...

    mrli2016 評(píng)論0 收藏0
  • 聊聊Dubbo - Dubbo擴(kuò)展機(jī)制源碼解析

    摘要:什么是類那什么樣類的才是擴(kuò)展機(jī)制中的類呢類是一個(gè)有復(fù)制構(gòu)造函數(shù)的類,也是典型的裝飾者模式。代碼如下有一個(gè)參數(shù)是的復(fù)制構(gòu)造函數(shù)有一個(gè)構(gòu)造函數(shù),參數(shù)是擴(kuò)展點(diǎn),所以它是一個(gè)擴(kuò)展機(jī)制中的類。 摘要:?在Dubbo可擴(kuò)展機(jī)制實(shí)戰(zhàn)中,我們了解了Dubbo擴(kuò)展機(jī)制的一些概念,初探了Dubbo中LoadBalance的實(shí)現(xiàn),并自己實(shí)現(xiàn)了一個(gè)LoadBalance。是不是覺(jué)得Dubbo的擴(kuò)展機(jī)制很不錯(cuò)呀...

    lmxdawn 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<