First, usage
The Activate annotation Indicates whether an extension is activated (used) and can be placed on the class definition and method, Dubbo it on the SPI extension class definition, indicating that the extension implements the activation condition and timing.
@Activate (group =Constants.provider) Public classDrpcserverinterceptorImplementsfilter{Private FinalServerrequestinterceptor Serverrequestinterceptor; Private FinalServerresponseinterceptor Serverresponseinterceptor; PublicDrpcserverinterceptor () {String Sendurl=Zipkinconfig.getproperty (zipkinconstants.send_address); Sender Sender=okhttpsender.create (Sendurl); Reporter<zipkin. Span> reporter =Asyncreporter.builder (Sender). build (); String Application= Zipkinconfig.getproperty (Zipkinconstants.brave_name);//Rpccontext.getcontext (). GETURL (). GetParameter ("Application");Brave brave =NewBrave.builder (application). Reporter (Reporter). build (); This. Serverrequestinterceptor =Brave.serverrequestinterceptor (); This. Serverresponseinterceptor =Brave.serverresponseinterceptor (); }。。。。 }
Indicates that the class is only valid for the producer.
Second, source code analysis
First look at the interface definition:
@Documented @retention (retentionpolicy.runtime) @Target ({elementtype.type, elementtype.method}) Public@InterfaceActivate {/*** Group Filter conditions. * <br/> * contains {@linkExtensionloader#getactivateextension} to the value given by the group parameter, the extension is returned. * <br/> * Does not filter if no group setting is set. */string[] Group ()default {}; /*** Key filter conditions. Contains {@linkextensionloader#getactivateextension} The URL of the parameter key has, then returns the extension. * <p/> * Example:<br/> * Annotation value <code> @Activate ("Cache,validatioin") </code>@linkextensionloader#getactivateextension} has a URL parameter of <code>cache</code>key, or <code>validatioin </code> returns the extension. * <br/> * If not set, it is not filtered. */string[] Value ()default {}; /*** Sorting information, can not be provided. */string[] before ()default {}; /*** Sorting information, can not be provided. */string[] After ()default {}; /*** Sorting information, can not be provided. */ intOrder ()default0;}
It has two fields that set the filter criteria, and Group,value are all character arrays. Used to specify under what conditions this extension class is activated.
The following is illustrated by several extensions to the Com.alibaba.dubbo.rpc.filter interface.
// such as Monitorfilter@Activate (group = {constants.provider, constants.consumer}) Public Classimplements Filter {}
Indicates that if the filter consumer (specified by group) belongs to Constants.provider (service provider) or Constants.consumer (service consumer), the filter is activated.
// look at this extension @Activate (group = constants.provider, value = constants.token_key) Public Classimplements Filter {}
Indicates that if the filter consumer (specified by group) belongs to Constants.provider (service provider) and the URL has parameter Constants.token_key (TOKEN), it is activated using this filter.
Then look at the specific implementation:
Dubbo in the Extensionloader class, when parsing an interface extension implementation class, all of the implementation classes that have activate annotations are placed first in a global map.
Activate Activate = clazz.getannotation (Activate. Class); if NULL { // If any, join, cachedactivates Map Extension: Implements Class class, Form cachedactivates.put (names[0 ], activate);}
4 methods are then provided to use cachedactivates specifically to return the extension to be used for activation.
/*** This was equivalent to <pre> * getactivateextension (URL, key, null); * </pre> * In all activations, to use the extension specified by key *@paramURL URL *@paramkey URL parameter key which used to get extension point names *@returnextension list which is activated. * @see#getActivateExtension (Com.alibaba.dubbo.common.URL, String, String)*/ PublicList<t>getactivateextension (URL url, String key)/*** This was equivalent to <pre> * getactivateextension (URL, Url.getparameter (key). Split (","), null); * </pre> * In all activations, the group to be specified plus the extension specified with key *@paramURL URL *@paramkey URL parameter key which used to get extension point names *@paramGroup Group *@returnextension list which is activated. * @see#getActivateExtension (Com.alibaba.dubbo.common.URL, string[], String)*/ PublicList<t>getactivateextension (URL url, string key, string group)/*** This was equivalent to <pre> * getactivateextension (URL, values, null); * </pre> * In all activations, the values specified in the extension *@paramURL URL *@paramvalues extension point names *@returnextension list which is activated *@see#getActivateExtension (Com.alibaba.dubbo.common.URL, string[], String)*/ PublicList<t>getactivateextension (URL url, string[] values)//In the end, there are the following methods to achieve /*** Get activate extensions. * Load Active extension *@paramURL URL *@paramvalues extension point names *@paramGroup Group *@returnextension list which is activated *@seecom.alibaba.dubbo.common.extension.Activate*/ PublicList<t>getactivateextension (URL url, string[] values, String group) {List<T> exts =NewArraylist<t>(); List<String> names = values = =NULL?NewArraylist<string> (0): Arrays.aslist (values); if(!names.contains (Constants.remove_value_prefix +Constants.default_key)) {getextensionclasses (); //cachedactivates The MAP structure Interface implementation extension: The Activate object on it for(Map.entry<string, Activate> entry:cachedActivates.entrySet ()) {//traverse all activate annotation objectsString name = Entry.getkey ();//SPI ExtensionActivate Activate =Entry.getvalue (); if(Ismatchgroup (Group, Activate.group ())) {//If there is a group matchT ext = getextension (name);//Add in extension class//name is not in the values specified column, and the name is not excluded, and the value of activate has a corresponding parameter in the URL, even if it is activated if(!names.contains (name)&&!names.contains (Constants.remove_value_prefix +name)&&isActive (activate, URL)) { //Exts.add (EXT); } } } //The Comparator interface Compare method is realized in the activatecomparator of the sort activate .Collections.sort (exts, activatecomparator.comparator); } List<T> Usrs =NewArraylist<t>(); for(inti = 0; I < names.size (); i++) {String name=Names.get (i); if(!Name.startswith (Constants.remove_value_prefix)&&!names.contains (Constants.remove_value_prefix +name)) { //traverse all extensions that are not excluded if(Constants.DEFAULT_KEY.equals (name)) {if(Usrs.size () > 0) {Exts.addall (0, Usrs); Usrs.clear (); } } Else { //add to result set by extension, load extensionT ext =getextension (name); Usrs.add (EXT); } } } if(Usrs.size () > 0) {exts.addall (USRS); } //returns an activation extension that meets the criteria returnexts; }
Dubbo series Seven, Dubbo @Activate annotation Use and implementation analysis