Dagger2 Generating Code Learning

Source: Internet
Author: User

After an article introduced the preliminary use of Dagger2, I believe that people who have just contacted will feel very strange, how there will be a lot of their own undefined code appears, why component is created in that way. In order to understand these things, we need to look at the source code generated by Dagger2. Dagger2 is a DI framework, and learning generated code can also better understand how Dagger2 is doing dependency injection.

Open the project in the previous article in Sublimetext, with the following structure:

You can see that appcomponent generated the daggerappcomponent,dagger2 build rule, and our custom component is generated with the prefix "Dagger". In addition, each @provides method in the module generates a factory class, and the naming convention is very regular. Here dagger a total of 6 classes generated for us: Daggerappcomponent/appmodule_provideapplicationfactory/reposlistactivity_membersinjector/ Githubapimodule_provideretrofitfactory/githubapimodule_provideokhttpclientfactory/githubapimodule_ Providegithubservicefactory. Let's take a look at the specifics of these classes.

First Look at Daggerappcomponent:

@Generated ("Dagger.internal.codegen.ComponentProcessor") Public Final classDaggerappcomponentImplementsAppComponent {PrivateProvider<application>Provideapplicationprovider; PrivateProvider<okhttpclient>Provideokhttpclientprovider; PrivateProvider<retrofit>Provideretrofitprovider; PrivateProvider<githubapiservice>Providegithubserviceprovider; PrivateMembersinjector<reposlistactivity>Reposlistactivitymembersinjector; Privatedaggerappcomponent (Builder builder) {assertBuilder! =NULL;  Initialize (builder); }   Public StaticBuilder Builder () {return NewBuilder (); }  Private voidInitializeFinalBuilder Builder) {       This. Provideapplicationprovider =appmodule_provideapplicationfactory.create (Builder.appmodule);  This. Provideokhttpclientprovider =githubapimodule_provideokhttpclientfactory.create (Builder.githubapimodule);  This. Provideretrofitprovider =githubapimodule_provideretrofitfactory.create (Builder.githubapimodule, Provideapplicationprovider,    Provideokhttpclientprovider);  This. Providegithubserviceprovider =githubapimodule_providegithubservicefactory.create (Builder.githubapimodule, Provideretrofitprovider);  This. Reposlistactivitymembersinjector =reposlistactivity_membersinjector.create (Membersinjector) Membersinjectors.noop (),  Providegithubserviceprovider); } @Override Public voidinject (reposlistactivity activity) {reposlistactivitymembersinjector.injectmembers (activity); }   Public Static Final classBuilder {PrivateAppmodule Appmodule; PrivateGithubapimodule Githubapimodule; PrivateBuilder () {} PublicAppComponent Build () {if(Appmodule = =NULL) {        Throw NewIllegalStateException ("Appmodule must be set"); }      if(Githubapimodule = =NULL) {         This. Githubapimodule =NewGithubapimodule (); }      return NewDaggerappcomponent ( This); }       PublicBuilder appmodule (appmodule appmodule) {if(Appmodule = =NULL) {        Throw NewNullPointerException ("Appmodule"); }       This. Appmodule =Appmodule; return  This; }       PublicBuilder githubapimodule (githubapimodule githubapimodule) {if(Githubapimodule = =NULL) {        Throw NewNullPointerException ("Githubapimodule"); }       This. Githubapimodule =Githubapimodule; return  This; }  }}

This is the case when we instantiate the Appcomponent in application:

AppComponent = Daggerappcomponent.builder ()        . Githubapimodule (new  githubapimodule ())        . Appmodule (new appmodule (this))        . Build ();

The first time I saw you must feel a group of fog, why do you write it? As you can see from the Daggerappcomponent code above, the builder mode is used. Let's review what Appcomponent is like:

@Component (modules = {Appmodule.  Class, Githubapimodule. class })publicinterface  AppComponent {    //  inject    void inject (reposlistactivity activity);}

@component later modules contains two classes, in the generated daggerappcomponent in the inner class builder, Appmodule.class and Githubapimodule.class become members of the and provides a set method. The process of instantiating daggerappcomponent in application actually calls its set method to set dependencies. Also in Daggerappcomponent the method return type of each @provides annotation is one of its member variables and is created in the Initialize () method. There is also a Membersinjector member, and Daggerappcomponent is responsible for creating it.

@Generated ("Dagger.internal.codegen.ComponentProcessor") Public Final classReposlistactivity_membersinjectorImplementsMembersinjector<reposlistactivity> {  Private FinalMembersinjector<baseactivity>Supertypeinjector; Private FinalProvider<githubapiservice>Githubapiserviceprovider;  PublicReposlistactivity_membersinjector (membersinjector<baseactivity> supertypeinjector, Provider< Githubapiservice>Githubapiserviceprovider) {      assertSupertypeinjector! =NULL;  This. Supertypeinjector =Supertypeinjector; assertGithubapiserviceprovider! =NULL;  This. Githubapiserviceprovider =Githubapiserviceprovider; } @Override Public voidInjectmembers (reposlistactivity instance) {if(Instance = =NULL) {      Throw NewNullPointerException ("Cannot inject" into a null reference ");    } supertypeinjector.injectmembers (instance); Instance.githubapiservice=Githubapiserviceprovider.get (); }   Public StaticMembersinjector<reposlistactivity> Create (membersinjector<baseactivity> supertypeInjector, Provider <GithubApiService>Githubapiserviceprovider) {        return NewReposlistactivity_membersinjector (Supertypeinjector, Githubapiserviceprovider); }}

An instance of the reposlistactivity is obtained through the Injectmembers method in the Reposlistactivity_membersinjector (corresponding to the Reposlistactivitycomponent in the inject), and then assign the value. From this method of assignment, the injected object of the @inject annotation cannot be private. In view of the assignment is obtained through the Githubapiserviceprovider.get () method, Githubapiserviceprovider is a factory class, let's see how this factory class is:

@Generated ("Dagger.internal.codegen.ComponentProcessor") Public Final classGithubapimodule_providegithubservicefactoryImplementsFactory<githubapiservice> {  Private FinalGithubapimodule module; Private FinalProvider<retrofit>Retrofitprovider;  PublicGithubapimodule_providegithubservicefactory (githubapimodule module, provider<retrofit>Retrofitprovider) {      assertModule! =NULL;  This. module =module; assertRetrofitprovider! =NULL;  This. Retrofitprovider =Retrofitprovider;  }。 @Override PublicGithubapiservice Get () {Githubapiservice provided=Module.providegithubservice (Retrofitprovider.get ()); if(Provided = =NULL) {      Throw NewNullPointerException ("Cannot return null from a [email protected] @Provides method"); }    returnprovided; }   Public StaticFactory<githubapiservice> Create (githubapimodule module, provider<retrofit>Retrofitprovider) {      return Newgithubapimodule_providegithubservicefactory (module, retrofitprovider); }}

There are two members in the Githubapimodule_providegithubservicefactory class, and one is the module class where the (@Provides) Githubservice is provided. One is the retrofitprovider of the parameters required to create the Githubservice method (from here you can see Dagger2 need to create a retrofitprovider factory). The Githubapiservice instance is then created through the Module.provdegithubservice () method, which eventually wears a dependent instance injected into the reposlistactivity.

Dagger2 get a little bit around, and don't find any systematic information, but you can see the framework automatically generated classes to deepen understanding, easy to use. Use to dependencies and subcomponent annotations when generated code is more, originally also want to smoothed, but the principle and above are the same, we go to see it.

Dagger2 Generating Code Learning

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.