dagger2入门指南Coffee浅析

本文详细解析了如何使用Dagger2在CoffeeApp中通过Component返回CoffeeMaker和CoffeeLogger对象,并介绍了如何注入Heater和Pump,以及保证全局唯一性和使用注解的方法。
摘要由CSDN通过智能技术生成


如果学dagger2有些糊涂了,不妨来点简单的提升一下信心!

Dagger2 Coffee App实现浅析

官方提供了Coffee App,演示Dagger2 使用。其内容真的有些简单,下面就简单分析一下其实现过程

Component返回目标对象

我们的目标是 完成Coffee 制作并打印制作过程。显然我们要定义Component返回CoffeeMaker && CoffeeLogger对象。

  @Component
  public interface CoffeeShop {
    CoffeeMaker maker();
    CoffeeLogger logger();
  }

注入CoffeeMaker对象

public class CoffeeMaker {
  private final CoffeeLogger logger;
  private final Lazy<Heater> heater; // Create a possibly costly heater only when we use it.
  private final Pump pump;

 
  CoffeeMaker(CoffeeLogger logger, Lazy<Heater> heater, Pump pump) {
    this.logger = logger;
    this.heater = heater;
    this.pump = pump;
  }

  public void brew() {
    heater.get().on();
    pump.pump();
    logger.log(" [_]P coffee! [_]P ");
    heater.get().off();
  }
}

显然,为了实现CoffeeMaker对象注入,最简单的方式在构造函数添加@Inject注解。为了符合单一原则,CoffeeMaker内部需要的CoffeeLogger、Heater、Pump都需要从外部进行注入,下面依次分析。

注入CoffeeLogger

CoffeeLogger 工具类原始代码如下:

public final class CoffeeLogger {
  private final List<String> logs = new ArrayList<>();

  CoffeeLogger() {}

  public void log(String msg) {
    logs.add(msg);
  }

  public List<String> logs() {
    return new ArrayList<>(logs);
  }
}

最简单的注入方式莫过于给构造函数添加@Inject注解。

注入Heater

Heater接口源码如下:

public interface Heater {
  void on();
  void off();
  boolean isHot();
}

不能直接注入接口,需要提供实现类和Module进行类型转换

public class ElectricHeater implements Heater {

  private final CoffeeLogger logger;
  private boolean heating;

  @Inject
  ElectricHeater(CoffeeLogger logger) {
    this.logger = logger;
  }

  @Override
  public void on() {
    this.heating = true;
    logger.log("~ ~ ~ heating ~ ~ ~");
  }

  @Override
  public void off() {
    this.heating = false;
  }

  @Override
  public boolean isHot() {
    return heating;
  }
}

@Module
interface HeaterModule {
  @Binds
  Heater bindHeater(ElectricHeater impl);
}

给实现类构造函数添加@Inject注解,在Module下写一个@Binds修饰的函数,参数为实现类、返回值为接口。也是可以实现的最简单的方式。

为了CoffeeShop可以使用HeaterModule,将HeaterModule添加到CoffeeShop的modules参数中。

注入Pump

public interface Pump {
  void pump();
}
public class Thermosiphon implements Pump {
  private final CoffeeLogger logger;
  private final Heater heater;

  @Inject
  Thermosiphon(CoffeeLogger logger, Heater heater) {
    this.logger = logger;
    this.heater = heater;
  }

  @Override
  public void pump() {
    if (heater.isHot()) {
      logger.log("=> => pumping => =>");
    }
  }
}

@Module
abstract class PumpModule {
  @Binds
  abstract Pump providePump(Thermosiphon pump);
}

这个和Heater注入完全一样。

保证全局唯一CoffeeLogger

这个很好理解,Heater、Pump如果都创建一个CoffeeLogger,就不可能将日志记录完整。因此将CoffeeLogger和CoffeeShop都添加上@Singleton注解。

保证Heater全局唯一

Thermosiphon.pump()中判断heater状态,如果不能保证单例,判断状态也没有任何意义。对于接口的实现方式,就只能在@Binds修饰的函数上进行添加。

注解说明

https://dagger.dev/dev-guide/

完整代码

https://gitee.com/guchuanhang/dagger2-coffee-app

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值