zoukankan      html  css  js  c++  java
  • 使用Dagger2创建的第一个小样例

    将Dagger系列的咖啡壶样例再做一下简化,作为Dagger2的入门的第一个小样例。

    场景描写叙述:有一个电水壶,它使用一个加热器来烧水。电水壶具备的功能有:開始加热(on方法),结束加热(off方法),倒水(brew方法)。

    正确使用Dagger2要依照下面5个步骤来进行:

    1.确定依赖对象和被依赖对象

    本例中。水壶是依赖对象(dependent object),加热器是被依赖对象(dependent object’s dependency)。而与此同一时候,加热器本身并不依赖谁,所以它是一个独立的个体(independent model)。

    加热器:src/bean/Heater.java

    public class Heater {
    	private boolean isHot;
    	public void on(){
    		System.out.println("開始烧开水啦");
    		isHot = true;
    	}
    	public void off(){
    		System.out.println("关闭加热器");
    		isHot = false;
    	}
    	public boolean isHot(){
    		return isHot;
    	}
    }
    


    电水壶:src/bean/Kettle.java

    public class Kettle {
    	private Heater heater;//电水壶依赖于加热器
    	
    	public Kettle(Heater heater) {
    		super();
    		this.heater = heater;
    	}
    	public void on(){
    		heater.on();
    	}
    	public void off(){
    		heater.off();
    	}
    	public void brew(){
    		if(heater.isHot()){
    			System.out.println("倒一杯开水");
    		}
    	}
    }

    2.创建@Module类

    Module类的作用就是提供各种方法,来返回满足依赖关系的对象。这些方法须要加入上@Provides注解。

    src/module/KettleModule.java

    @Module
    public class KettleModule {
    	@Singleton
    	@Provides
    	Heater providesHeater(){
    		return new Heater();
    	}
    	@Singleton
    	@Provides
    	Kettle providesKettle(Heater heater){
    		return new Kettle(heater);
    	}
    }


    3.当有了@Module类,提供所需的依赖和被依赖对象,那么我们就在须要的地方进行取用就可以。

    取用的方式是通过@Inject注解。如今改动下面之前的Kettle类:

    <pre name="code" class="java" style="font-size: 18px;">public class Kettle {
    	private Heater heater;//电水壶依赖于加热器
    	<span style="color:#ff6666;">@Inject</span>
    	public Kettle(Heater heater) {
    		super();
    		this.heater = heater;
    	}
    	public void on(){
    		heater.on();
    	}
    	public void off(){
    		heater.off();
    	}
    	public void brew(){
    		if(heater.isHot()){
    			System.out.println("倒一杯开水");
    		}
    	}
    }

    
    唯一改动的就是为构造器加入了@Inject注解。

    Dagger2中。@Inject注解能够加入在构造器、方法和属性本身的前面。本例就通过构造器进行注入。

    4.创建一个接口,让@Inject和@Module建立起联系

    写一个接口,并用@Component进行注解。该注解有一个属性module。它用来指明与@Inject建立联系的将是哪一个(或哪一些)@Module类。假设@Inject和@Module匹配正确,那么在接口中定义的方法的返回值对象,都将是被正确注入了依赖关系的对象了:

    src/module/KettleComponent:

    @Singleton
    @Component(modules=KettleModule.class)
    public interface KettleComponent {
    	Kettle providesKettle();
    }
    

    5.获得第4步中声明的接口对象的实例,进而获得接口中定义方法的返回值

    @Component接口的实现类由Dagger2自己主动生成。这个类的命名规范是Dagger前缀加上@Component类的名称,那么本例中,这个类的名称就是DaggerKettleComponent了。

    写一个測试类,測试一下注入的结果:

    src/main/Test:

    public class Test {
    	public static void main(String[] args) {
    		KettleComponent component = DaggerKettleComponent.builder().build();
    		Kettle kettle = component.providesKettle();
    		kettle.on();
    		kettle.brew();
    		kettle.off();
    	}
    }

    这里一定要注意,DaggerKettleComponent类是Daager2依据注解自己主动生成的一个类。我们能够看一下这个类的源代码。就知道为什么要这么调用才干生成一个KettleComponent对象了。

    @Generated("dagger.internal.codegen.ComponentProcessor")
    public final class DaggerKettleComponent implements KettleComponent {
      private Provider<Heater> providesHeaterProvider;
      private Provider<Kettle> providesKettleProvider;
    
      private DaggerKettleComponent(Builder builder) {  
        assert builder != null;
        initialize(builder);
      }
    
      public static Builder builder() {  
        return new Builder();
      }
    
      public static KettleComponent create() {  
        return builder().build();
      }
    
      private void initialize(final Builder builder) {  
        this.providesHeaterProvider = ScopedProvider.create(KettleModule_ProvidesHeaterFactory.create(builder.kettleModule));
        this.providesKettleProvider = ScopedProvider.create(KettleModule_ProvidesKettleFactory.create(builder.kettleModule, providesHeaterProvider));
      }
    
      @Override
      public Kettle providesKettle() {  
        return providesKettleProvider.get();
      }
    
      public static final class Builder {
        private KettleModule kettleModule;
      
        private Builder() {  
        }
      
        public KettleComponent build() {  
          if (kettleModule == null) {
            this.kettleModule = new KettleModule();
          }
          return new DaggerKettleComponent(this);
        }
      
        public Builder kettleModule(KettleModule kettleModule) {  
          if (kettleModule == null) {
            throw new NullPointerException("kettleModule");
          }
          this.kettleModule = kettleModule;
          return this;
        }
      }
    }

    DaggerKettleComponent实现了KettleCommpoment接口,并重写了providesKettle方法。

    首先调用静态方法builder是为了创建静态内部类Builder类的对象,创建对象后调用方法kettleModule方法为Builder的kettleModule属性赋值,随后再调用静态内部类Builder对象的build方法创建DaggerKettleComponent的对象。

    在DaggerKettleComponent构造器中会首先对静态内部类Builder对象进行一下判空,然后调用initialize(builder)方法,利用这个静态内部类Builder对象为自己的两个属性赋值:providesHeaterProvider属性和providesKettleProvider属性。而且providesKettleProvider属性值的创建要依赖于providesHeaterProvider属性值。随着providesHeaterProvider属性和providesKettleProvider属性初始化完成,DaggerKettleComponent对象也就创建完成了。

    当调用providesKettle方法的时候。返回的是providesKettleProvider的get方法的返回值。

    最后測试程序的运行结果为:

     

  • 相关阅读:
    [LeetCode]题解(python):136-Single Number
    [LeetCode]题解(python):135-Candy
    [LeetCode]题解(python):134-Gas Station
    [LeetCode]题解(python):133-Clone Graph
    [LeetCode]题解(python):132-Palindrome Partitioning II
    [LeetCode]题解(python):131-Palindrome Partitioning
    [LeetCode]题解(python):130-Surrounded Regions
    [LeetCode]题解(python):129-Sum Root to Leaf Numbers
    [LeetCode]题解(python):128-Longest Consecutive Sequence
    [LeetCode]题解(python):127-Word Ladder
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7063822.html
Copyright © 2011-2022 走看看