Before you write code, look at the source of Dubbo.
The basic usage of Dubbo can be viewed in my blog
http://www.qbmmj.com/tag/dubbo/
Dubbo can configure services registered to the registry in the form of XML or annotations
Let's take a look at how the XML works, in the Dubbo source package directory We can find two spring files, the following figure ↓
Let's take a look at the head portion of the configuration file that is most viewed using XML configuration, as shown below ↓
When loaded into this configuration file, it will be loaded into the Dubbo, and then let's see spring.handlers this file, below is his code ↓
Http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.dubbonamespacehandler
Let's take a look at this class, below is the source ↓
* * Copyright 1999-2011 Alibaba Group.
* Licensed under the Apache License, Version 2.0 (the "License");
* You could not use this file, except in compliance with the License. * Obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * unless required
By applicable or agreed into writing, software * Distributed under the License is distributed on ' as is ' basis,
* Without warranties or CONDITIONS of any KIND, either express or implied.
* The License for the specific language governing permissions and * limitations under the License.
* * Package Com.alibaba.dubbo.config.spring.schema;
Import Org.springframework.beans.factory.xml.NamespaceHandlerSupport;
Import com.alibaba.dubbo.common.Version;
Import Com.alibaba.dubbo.config.ApplicationConfig;
Import Com.alibaba.dubbo.config.ConsumerConfig;
Import Com.alibaba.dubbo.config.ModuleConfig;
Import Com.alibaba.dubbo.config.MonitorConfig; Import Com.alibaba.dubbo.config.ProtoColconfig;
Import Com.alibaba.dubbo.config.ProviderConfig;
Import Com.alibaba.dubbo.config.RegistryConfig;
Import Com.alibaba.dubbo.config.spring.AnnotationBean;
Import Com.alibaba.dubbo.config.spring.ReferenceBean;
Import Com.alibaba.dubbo.config.spring.ServiceBean; /** * Dubbonamespacehandler * * @author WILLIAM.LIANGF * * @export/public class Dubbonamespacehandler extends Names
Pacehandlersupport {static {version.checkduplicate (Dubbonamespacehandler.class); public void init () {Registerbeandefinitionparser ("Application"), New Dubbobeandefinitionparser (Applicationc
Onfig.class, True));
Registerbeandefinitionparser ("module", New Dubbobeandefinitionparser (Moduleconfig.class, true));
Registerbeandefinitionparser ("Registry", New Dubbobeandefinitionparser (Registryconfig.class, true));
Registerbeandefinitionparser ("Monitor", New Dubbobeandefinitionparser (Monitorconfig.class, true)); Registerbeandefinitionparser ("ProvideR ", New Dubbobeandefinitionparser (Providerconfig.class, true));
Registerbeandefinitionparser ("Consumer", New Dubbobeandefinitionparser (Consumerconfig.class, true));
Registerbeandefinitionparser ("Protocol", new Dubbobeandefinitionparser (Protocolconfig.class, true));
Registerbeandefinitionparser ("service", New Dubbobeandefinitionparser (Servicebean.class, true));
Registerbeandefinitionparser ("Reference", New Dubbobeandefinitionparser (Referencebean.class, false));
Registerbeandefinitionparser ("annotation", New Dubbobeandefinitionparser (Annotationbean.class, true)); }
}
This class inherits Namespacehandlersupport he has a top-level interface namespacehandler,parse and decorate methods have been implemented in Namespacehandlersupport, This time Dubbonamespacehandler implements the Init method and makes a fault-tolerant check of the version number, which is a static block. The purpose of this class is to parse the Dubbo tag, and when the spring container starts, it drops the Init method in the Dubbonamespacehandler, By looking at the source width to find that the processing of the bean in the label is handled through Dubbobeandefinitionparser, This class implements the Beandefinitionparser interface to rewrite the Pase method to invoke a static Pase method in Pase to do the processing. The different Dubbo tags are parsed by passing in a different parameter in the construct.
So far, the operation that transforms the XML into spring's bean definition is over. Let's take a look at the comparison core Servicebean creation ↓
First look at the source of Servicebean, the bottom of the source ↓ posted
* * Copyright 1999-2011 Alibaba Group.
* Licensed under the Apache License, Version 2.0 (the "License");
* You could not use this file, except in compliance with the License. * Obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * unless required
By applicable or agreed into writing, software * Distributed under the License is distributed on ' as is ' basis,
* Without warranties or CONDITIONS of any KIND, either express or implied.
* The License for the specific language governing permissions and * limitations under the License.
* * Package com.alibaba.dubbo.config.spring;
Import Java.lang.reflect.Method;
Import java.util.ArrayList;
Import java.util.List;
Import Java.util.Map;
Import Org.springframework.beans.factory.BeanFactoryUtils;
Import Org.springframework.beans.factory.BeanNameAware;
Import Org.springframework.beans.factory.DisposableBean;
Import Org.springframework.beans.factory.InitializingBean; import org. Springframework.context.ApplicationContext;
Import Org.springframework.context.ApplicationContextAware;
Import org.springframework.context.ApplicationEvent;
Import Org.springframework.context.ApplicationListener;
Import org.springframework.context.event.ContextRefreshedEvent;
Import Org.springframework.context.support.AbstractApplicationContext;
Import Com.alibaba.dubbo.config.ApplicationConfig;
Import Com.alibaba.dubbo.config.ModuleConfig;
Import Com.alibaba.dubbo.config.MonitorConfig;
Import Com.alibaba.dubbo.config.ProtocolConfig;
Import Com.alibaba.dubbo.config.ProviderConfig;
Import Com.alibaba.dubbo.config.RegistryConfig;
Import Com.alibaba.dubbo.config.ServiceConfig;
Import Com.alibaba.dubbo.config.annotation.Service;
Import Com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory; /** * Servicefactorybean * * @author WILLIAM.LIANGF * * @export/public class Servicebean<t> extends Serviceco Nfig<t> implements Initializingbean, Disposablebean, ApplicatIoncontextaware, Applicationlistener, beannameaware {private static final long Serialversionuid = 213195494150089726
L
private static transient ApplicationContext spring_context;
private transient applicationcontext applicationcontext;
private transient String beanname;
Private transient Boolean supportedapplicationlistener;
Public Servicebean () {super ();
Public Servicebean (Service service) {super (service);
public static ApplicationContext Getspringcontext () {return spring_context; } public void Setapplicationcontext (ApplicationContext applicationcontext) {this.applicationcontext = Applic
Ationcontext;
Springextensionfactory.addapplicationcontext (ApplicationContext);
if (ApplicationContext!= null) {spring_context = ApplicationContext; try {Method method = Applicationcontext.getclass (). GetMethod ("Addapplicationlistener", New class<? >[]{applicationlistener.class});
Compatible Spring2.0.1 Method.invoke (ApplicationContext, new object[] {this});
Supportedapplicationlistener = true;
The catch (Throwable t) {if (ApplicationContext instanceof Abstractapplicationcontext) { try {Method method = AbstractApplicationContext.class.getDeclaredMethod ("AddListener", New Clas S<?>[]{applicationlistener.class}); Compatible Spring2.0.1 if (! method.isaccessible ()) {method.setaccessible (t
Rue);
} method.invoke (ApplicationContext, new object[] {this});
Supportedapplicationlistener = true; The catch (Throwable t2) {}}} is public void Setbeannam
E (String name) {this.beanname = name; } public void OnapplicationevENT (Applicationevent event) {if (ContextRefreshedEvent.class.getName (). Equals (Event.getclass (). GetName ())) { if (Isdelay () &&! isexported () &&! isunexported ()) {if (logger.isinfoenabled ()) {Logger.info ("The Service ready on spring started.")
Service: "+ getinterface ());
Export ();
}} private Boolean Isdelay () {Integer delay = Getdelay ();
Providerconfig Provider = Getprovider ();
if (delay = = NULL && provider!= null) {delay = Provider.getdelay ();
return Supportedapplicationlistener && (delay = NULL | | | delay.intvalue () = = 1); @SuppressWarnings ({"Unchecked", "deprecation"}) public void Afterpropertiesset () throws Exception {I F (getprovider () = null) {map<string, providerconfig> providerconfigmap = ApplicationContext = null? Null: Beanfactoryutils.beansoftypeincludingancestors (ApplicationContext, Providerconfig.class, False, false); if (providerconfigmap!= null && providerconfigmap.size () > 0) {map<string, protocolconfig& Gt Protocolconfigmap = ApplicationContext = = null?
Null:BeanFactoryUtils.beansOfTypeIncludingAncestors (ApplicationContext, Protocolconfig.class, False, false); if ((Protocolconfigmap = null | | protocolconfigmap.size () = 0) && Providerconfigm Ap.size () > 1) {//compatible with old version list<providerconfig> Providerconfigs = new Arraylist<providercon
Fig> (); For (Providerconfig config:providerConfigMap.values ()) {if (Config.isdefault ()!= null &&am P
Config.isdefault (). Booleanvalue ()) {providerconfigs.add (config); } if (providerconfigs.size() > 0) {setproviders (providerconfigs);
} else {providerconfig providerconfig = null; For (Providerconfig config:providerConfigMap.values ()) {if (config.isdefault () = null | | | confi
G.isdefault (). Booleanvalue ()) {if (providerconfig!= null) {
throw new IllegalStateException ("Duplicate provider configs:" + Providerconfig + "and" + config);
} providerconfig = config; } if (Providerconfig!= null) {Setprovider (providerconf
IG); if (getapplication () = = null && (Getprovider () = = NULL | | Getprovider (). getapplication () = null)) {map<string, Applicationconfig> Applicationconfigmap = ApplicationContext = null?
Null:BeanFactoryUtils.beansOfTypeIncludingAncestors (ApplicationContext, Applicationconfig.class, False, false); if (applicationconfigmap!= null && applicationconfigmap.size () > 0) {applicationconfig A
Pplicationconfig = null; For (Applicationconfig config:applicationConfigMap.values ()) {if (config.isdefault () = null | | | con Fig.isdefault (). Booleanvalue ()) {if (applicationconfig!= null) {THR
ow new IllegalStateException ("Duplicate application configs:" + Applicationconfig + "and" + config);
} applicationconfig = config; } if (Applicationconfig!= null) {setapplication (applicationconfig)
;
}} if (GetModule () = null && (getprovider () = null | | getprovider (). GetModule () = null)) {map<string, Module config> Moduleconfigmap = ApplicationContext = null?
Null:BeanFactoryUtils.beansOfTypeIncludingAncestors (ApplicationContext, Moduleconfig.class, False, false);
if (moduleconfigmap!= null && moduleconfigmap.size () > 0) {moduleconfig moduleconfig = null; For (Moduleconfig config:moduleConfigMap.values ()) {if (config.isdefault () = null || Config.isdefault (). Booleanvalue ()) {if (moduleconfig!= null) {throw
New IllegalStateException ("Duplicate module configs:" + moduleconfig + "and" + config);
} moduleconfig = config;
} if (moduleconfig!= null) {setmodule (moduleconfig);
}
} if (getregistries () = null | | getregistries (). Size () = 0) && (getprovider () = = Nu ll | | Getprovider (). getregistries () = NULL | | Getprovider (). Getregistries (). Size () = 0) && (getapplication () = null | | getapplication (). Getreg Istries () = = NULL | | Getapplication (). Getregistries (). Size () = 0)) {map<string, registryconfig> registryconfigmap = Applica Tioncontext = null?
Null:BeanFactoryUtils.beansOfTypeIncludingAncestors (ApplicationContext, Registryconfig.class, False, false); if (registryconfigmap!= null && registryconfigmap.size () > 0) {list<registryconfig> r
Egistryconfigs = new arraylist<registryconfig> (); For (Registryconfig config:registryConfigMap.values ()) {if (config.isdefault () = null | | | config.is
Default (). Booleanvalue ()) {registryconfigs.add (config);
} } if (Registryconfigs!= null && registryconfigs.size () > 0) {
Super.setregistries (Registryconfigs); }} if (Getmonitor () = = null && (getprovider () = NULL | | getprovide R (). Getmonitor () = = null) && (getapplication () = null | | getapplication (). Getmonitor () = null) {map<string, monitorconfig> monitorconfigmap = ApplicationContext = = null? null:BeanFactoryUtils.bea
Nsoftypeincludingancestors (ApplicationContext, Monitorconfig.class, False, false); if (monitorconfigmap!= null && monitorconfigmap.size () > 0) {monitorconfig monitorconfig = Nu
ll For (Monitorconfig config:monitorConfigMap.values ()) {if (config.isdefault () = null | | | config.isde
Fault (). Booleanvalue ()) {if (monitorconfig!= null) { throw new IllegalStateException ("Duplicate monitor configs:" + Monitorconfig + "and" + config);
} monitorconfig = config;
} if (Monitorconfig!= null) {setmonitor (monitorconfig); }} if ((getprotocols () = null | | getprotocols (). Size () = 0) && Amp (Getprovider () = = NULL | | getprovider (). Getprotocols () = null | | getprovider (). Getprotocols (). Size () = 0) {map<string, protocolconfig> protocolconfigmap = ApplicationContext = = null? null:beanfactoryutils.
Beansoftypeincludingancestors (ApplicationContext, Protocolconfig.class, False, false); if (protocolconfigmap!= null && protocolconfigmap.size () > 0) {list<protocolconfig> Pro
Tocolconfigs = new arraylist<protocolconfig> (); For (protocolconfig config:Protocolconfigmap.values ()) {if (config.isdefault () = null | | config.isdefault (). Booleanvalue ()) {
Protocolconfigs.add (config);
} if (Protocolconfigs!= null && protocolconfigs.size () > 0) {
Super.setprotocols (Protocolconfigs); }} if (GetPath () = null | | getpath (). Length () = 0) {if (Beanname!= null &am p;& beanname.length () > 0 && getinterface ()!= null && getinterface (). Length ()
> 0 && beanname.startswith (getinterface ())) {SetPath (beanname);
} if (! Isdelay ()) {export ();
} public void Destroy () throws Exception {Unexport (); }
}
Through the source wide to find that this class inherits the ServiceConfig implements five interfaces, respectively, is Initializingbean,disposablebean,applicationcontextaware, Applicationlistener,beannameaware, Bottom analysis
1. First of all, Initializingbean,disposablebean.
There are probably three ways to create and destroy Springbean: ① One is to specify @postconstruct and @PreDestroy through annotations Method ② If it is XML, you can specify Init-method and Destory-method③ to implement the Initializingbean,disposablebean by implementing two interfaces.
2.ApplicationContextAware
With this interface we can get the context of spring
3.ApplicationListener
The effect of this excuse is to be able to monitor the events that are used through Applicationcontext.publistevent (Applicationevent event), The Publistevent publish time is invoked at spring startup when the bean initialization completes, as long as the class that implements the Applicationlistener interface can receive time and respond. See the source wide to find that the monitor is contextrefreshedevent, below is the code ↓
public void Onapplicationevent (Applicationevent event) {