Motan Source Analysis II: Using the SPI mechanism for class loading _motan

Source: Internet
Author: User
Motan Source Analysis II: Using the SPI mechanism for class loading

Motan in the source code used a lot of SPI mechanism for the creation of objects, below we have a concrete analysis of its implementation methods.

1. In the actual jar package in the \meta-inf\services directory to introduce related files, such as the following image, I extracted the core jar file after the corresponding file list:

2. In the first section of the Confighandler as an example to analyze, Open the Com.weibo.api.motan.config.handler.ConfigHandler file in the previous figure, which identifies the implementation class for the Confighandler interface as: COM.WEIBO.API.MOTAN.CONFIG.HANDLER.S Impleconfighandler 1 2 3 4 5 6 7 8 9 A # #  copyright  2009-2016  Weibo, Inc. #&n bsp;   licensed under the Apache License, version  2.0  (the  "License"); #    you are not use  this  file except in compliance with the License. #    obtain a copy of the License at # #        http://www.apac he.org/licenses/license-2.0 # #    unless required by applicable and agreed to in writing, software #&nb sp;   distributed under the License is distributed on an  ' as is '   basis, #    without Warranties or CONDITIONS of any KIND, either express OR implied. #    the license  for  specific language governing permissions and #    limitations under the License. #   Com.weibo.api.motan.config.handler.SimpleConfigHandler

3. In the first section, the code to create the Confighandler object is this:

        Confighandler Confighandler = Extensionloader.getextensionloader (Confighandler.class). GetExtension ( Motanconstants.default_value);

4. Start into the core of the actual load code, first look at the specific implementation of the ClassLoader:

    public static <T> extensionloader<t> getextensionloader (class<t> type) {Checkinterfacetype ( type);//basic check extensionloader<t> loader = (extensionloader<t>) extensionloaders.get (type);//Whether it has been loaded before This loader if (loader = = null) {loader = Initextensionloader (type);//First Load} return loader
    ; private static <T> void Checkinterfacetype (class<t> clz) {if (CLZ = = null) {Failt
        Hrows (CLZ, "Error extension type is null");
        } if (!clz.isinterface ()) {failthrows (CLZ, "Error extension type is not interface");
        } if (!isspitype (CLZ)) {failthrows (CLZ, "Error extension type without @Spi annotation");
        } public static synchronized <T> extensionloader<t> Initextensionloader (class<t> type) {

     extensionloader<t> loader = (extensionloader<t>) extensionloaders.get (type);   if (loader = = null) {loader = new extensionloader<t> (type);//A newly created loader extensionloaders.

            Putifabsent (type, loader);
        Loader = (extensionloader<t>) extensionloaders.get (type);
    return loader; }

5. Below we will go to the inside of the loader to analyze the specific implementation:

    Private Extensionloader (class<t> type) {This (type, Thread.CurrentThread (). Getcontextclassloader ())//Use

        The class loader for the current thread is the loader, type is Confighandler interface} public T getextension (String name) {checkinit ();//Check initialization
        if (name = = NULL) {return null;

            try {SPI SPI = type.getannotation (Spi.class);
                if (spi.scope () = = Scope.singleton) {return getsingletoninstance (name);//Returns a unique object} else {

                class<t> CLZ = extensionclasses.get (name);
                if (CLZ = = null) {return null; return clz.newinstance ()///Recreate object} catch (Exception e) {failthrows (
        Type, "Error when GetExtension" + name, e);
    return null;
        Private synchronized void loadextensionclasses () {if (init) {return; } extensionclasses = LoadextensiOnclasses (PREFIX)//loading related class singletoninstances = new Concurrenthashmap<string, t> ();
    init = true; Private concurrentmap<string, class<t>> loadextensionclasses (string prefix) {string fullName = Prefix + type.getname ();//Full Name: Class List in jar package name +\meta-inf\services\com.weibo.api.motan.config.handler.confighandler file

        <String> classnames = new arraylist<string> ();
            try {enumeration<url> URLs;
            if (ClassLoader = = null) {urls = classloader.getsystemresources (fullName);
            else {urls = classloader.getresources (fullName); } if (url = null | |!urls.hasmoreelements ()) {return new concurrenthashmap<string, Clas
            S<t>> ();
            } System.out.println ("FullName:" +fullname);
                while (Urls.hasmoreelements ()) {URL url = urls.nextelement (); System.Out.println ("URL:" +url.getfile ());
            parseURL (type, URL, classnames); } catch (Exception e) {throw new Motanframeworkexception ("Extensionloader load
        extensionclasses error, prefix: "+ prefix +" type: "+ type.getclass (), E);
        for (String classn:classnames) {System.out.println ("class:" +CLASSN);
    Return LoadClass (Classnames); }

 6. Read the contents of the file in the parseURL method and complete the load of the class in LoadClass

    private void parseURL (class<t> type, url url, list<string> classnames) throws Serviceconfigurationerror {
        InputStream inputstream = null;
        BufferedReader reader = null;
            try {InputStream = Url.openstream ();

            reader = new BufferedReader (new InputStreamReader (InputStream, Motanconstants.default_character));
            String line = null;

            int IndexNumber = 0;
                while (line = Reader.readline ())!= null) {indexnumber++; ParseLine (type, URL, line, IndexNumber, classnames); Read to class name: Com.weibo.api.motan.config.handler.SimpleConfigHandler}} catch (Exception x) {F
        Aillog (Type, "Error reading SPI configuration file", x);
                Finally {try {if (reader!= null) {reader.close ();
             } if (InputStream!= null) {inputstream.close ();   The catch (IOException y) {faillog (type, "Error closing SPI configuration file", y);  }} private Concurrentmap<string, class<t>> loadclass (list<string> classnames)

        {concurrentmap<string, class<t>> map = new concurrenthashmap<string, class<t>> ();
                for (String classname:classnames) {try {class<t> clz; if (ClassLoader = = null) {CLZ = (class<t>) class.forname (className);//Load class: COM.WEIBO.API.MOTAN.C Onfig.handler.SimpleConfigHandler} else {clz = (class<t>) class.forname (classn
                Ame, True, ClassLoader);

                } checkextensiontype (CLZ);

                String spiname = Getspiname (CLZ);
               if (Map.containskey (Spiname)) {failthrows (CLZ, ": Error spiname already" + exist); else {map.put (spiname, CLZ);
            The catch (Exception e) {faillog (type, Error load SPI class, E);

    } return map; }

Summary of knowledge points for Motan class loading:

1. Using the SPI specification of JDK, add the actual usage class description in \meta-inf\services, thus realizing the complete decoupling between class and class;

2. The class loader uses the class loader of the current thread;

The 3.motan ClassLoader can support both single and multiple modes;

The class loading method for SPI is heavily used in 4.motan.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.