Dagger2 注解使用Demo

  1. 案例一

  1. Car 类是需求依赖方,依赖了 Engine 类;因此我们需要在类变量 Engine 上添加@Inject 来告诉 Dagger2 来为自己提供依赖。 Engine 类是依赖提供方,因此我们需要在它的构造函数上添加@Inject

  class Engine {
      Logger logger = LoggerFactory.getLogger(this.getClass());
​
      /**
       * Dagger2 通过@Inject注解可以在需要这个类实例的时候来找到这个构造函数并把相关实例构造出来,
       * *  以此来为被@Inject 标记了的变量提供依赖     *
       */
      @Inject
      public Engine() {
      }
​
      @NonNull
      @Override
      public String toString() {
          return "Engine{}";
      }
​
      public void run() {
          logger.info( "引擎转起来了~~~ ");
      }
  }
  1. 接下来我们需要创建一个用@Component 标注的接口 CarComponent,这个 CarComponent 其实就是一个注入器,这里用来将 Engine 注入到 Car 中。

@Component
 interface CarComponent {
    void inject(Car car);
}
  1. 完成这些之后我们需要 Build 下项目,让 Dagger2 帮我们生成相关的 Java 类。接着我们就可以在 Car 的构造函数中调用 Dagger2 生成的 DaggerCarComponent 来实现注入(这其实在前面 Car 类的代码中已经有了体现)

  public class Car {
      /**
       * @Inject:@Inject 有两个作用,一是用来标记需要依赖的变量,以此告诉 Dagger2 为它提供依赖
       */
      @Inject
      Engine engine;
​
      public Car() {
          DaggerCarComponent.builder().build().inject(this);
      }
​
      public Engine getEngine() {
          return this.engine;
      }
​
      public static void main(String... args) {
          Car car = new Car();
          car.getEngine().run();
      }
  }
  1. 案例二、@Module、@Provide 的使用

  1. 如果创建 Engine 的构造函数是带参数的呢?或者 Eggine 类是我们无法修改的呢?这时候就需要@Module 和@Provide 上场了。可以看到下面 Engine 类的代码和上面的入门 demo 中的 Engine 代码几乎一样,只是多了个带参数的构造方法。

class Engine1 {
   private String name;
​
   @Inject
   Engine1() {
   }
​
   Engine1(String name) {
       this.name = name;
   }
​
   @Override
   public String toString() {
       return "Engine1{" + "name='" + name + '\'' + '}';
   }
​
   public void run() {
       System.out.println("引擎转起来了~~~");
   }
}

 

  1. 接着我们需要一个 Module 类来生成依赖对象。前面介绍的@Module 就是用来标准这个类的,而@Provide 则是用来标注具体提供依赖对象的方法(这里有个不成文的规定,被@Provide 标注的方法命名我们一般以 provide 开头,这并不是强制的但有益于提升代码的可读性)

  @Module
  class MarkCarModule {
      String engineType;
​
      public MarkCarModule(String engineType) {
          this.engineType = engineType;
      }
​
      @Provides
      Engine1 provideEngine() {
          return new Engine1(engineType);
      }
  }
  1. 接下来我们还需要对 CarComponent 进行一点点修改,之前的@Component 注解是不带参数的,现在我们需要加上 modules = {MarkCarModule.class},用来告诉 Dagger2 提供依赖的是 MarkCarModule 这个类。

@Component(modules = MarkCarModule.class)
interface CarComponent1 {
    void inject(Car1 car1);
}

 

  1. Car 类的构造函数我们也需要修改,相比之前多了个 markCarModule(new MarkCarModule())方法,这就相当于告诉了注入器 DaggerCarComponent 把 MarkCarModule 提供的依赖注入到了 Car 类中。

public class Car1 {
   @Inject
   Engine1 engine1;
​
   public Car1() {
       DaggerCarComponent1.builder().markCarModule(new MarkCarModule("国产发动机")).build().inject(this);
   }
​
   public Engine1 getEngine1() {
       return this.engine1;
   }
​
   public static void main(String... args) {
       Car1 car = new Car1();
       System.out.println(car.getEngine1());
   }
}

Dagger2 的依赖查找顺序说明 我们提到@Inject 和@Module 都可以提供依赖,那如果我们既在构造函数上通过标记@Inject 提供依赖,又通过@Module 提供依赖 Dagger2 会如何选择呢?具体规则如下:

步骤 1:首先查找@Module 标注的类中是否存在提供依赖的方法。

步骤 2:若存在提供依赖的方法,查看该方法是否存在参数。

a:若存在参数,则按从步骤 1 开始依次初始化每个参数;

b:若不存在,则直接初始化该类实例,完成一次依赖注入。

步骤 3:若不存在提供依赖的方法,则查找@Inject 标注的构造函数,看构造函数是否存在参数。

a:若存在参数,则从步骤 1 开始依次初始化每一个参数

b:若不存在,则直接初始化该类实例,完成一次依赖注入。

总结:Dagger2 依赖查找的顺序是先查找 Module 内所有的 @Provides 提供的依赖,如果查找不到再去查找 @Inject 提供的依赖。

  1. 案例三、@Qualifiers

通过@Qulifier 注解来自定义两个注解,用于区分返回类型相同但又是不同对象的两个具体类

class Engine {
    private String name;
​
    @Inject
    public Engine() {
    }
​
    public Engine(String name) {
        this.name = name;
    }
​
    public void run() {
        System.out.println(name + "启动了");
    }
}
/**
* 使用@Qulifier 定义两个注解
*/
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface QualifierA {
}
​
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface QualifierB {
}

同时我们需要对依赖提供方做出修改,用定义的不同的注解来给不同的 provideEngine 方法贴上标签,这样 Dagger2 在寻找同类型对象时,就知道到底应该找哪一个了

@Module
public class MarkCarModule {
    public MarkCarModule() {
    }
​
    @QualifierA
    @Provides
    Engine provideEngineA() {
        return new Engine("国产发动机");
    }
​
    @QualifierB
    @Provides
    Engine provideEngineB() {
        return new Engine("德国发动机");
    }
}

接下来依赖需求方 Car 类同样需要修改,需要在注入对象前加上自定义的注解便签,以便 Dagger2 知道选择哪个 provide 方法

public class Car {
    @QualifierA
    @Inject
    Engine engineA;
    @QualifierB
    @Inject
    Engine engineB;
​
    public Car() {
        DaggerCarComponent.builder().markCarModule(new MarkCarModule()).build().inject(this);
    }
​
    public Engine getEngineA() {
        return this.engineA;
    }
​
    public Engine getEngineB() {
        return this.engineB;
    }
​
    public static void main(String... args) {
        Car car = new Car();
        System.out.println(car.getEngineA());
        System.out.println(car.getEngineB());
    }
}
  1. 案例4、 @Name 注解

@Name 实际上也是 @Qualifier 注解的一个注解。原理还是 @Qualifier,只不过往上封装了一层使用起来可能更加方便

class Engine {
    private String name;
​
    @Inject
    public Engine() {
    }
​
    public Engine(String name) {
        this.name = name;
    }
​
    public void run() {
        System.out.println(name + "启动了");
    }
}
​
@Module
class MarkCarModule {
    public MarkCarModule() {
    }
​
    @Provides
    @Named("A")
    Engine provideEngineA() {
        return new Engine("国产发动机");
    }
​
    @Provides
    @Named("B")
    Engine provideEngineB() {
        return new Engine("德国发动机");
    }
​
    @Provides
    @Named("C")
    Engine provideEngineC() {
        return new Engine();
    }
}
​
@Component(modules = MarkCarModule.class)
interface CarComponent {
    void inject(Car car);
}
​
public class Car {
​
​
    @Inject
    @Named("C")
    Engine engine;
​
    public Car() {
        DaggerCarComponent.create().inject(this);
​
    }
​
    public Engine getEngine() {
        return engine;
    }
​
    public static void main(String[] args) {
        Car car = new Car();
        car.getEngine().run();
    }
}
  1. @singleton实现局部单例,是@scope的一个实现类

    1. 在 Module 对应的 Provides 方法标明@Singleton,表明提供的是一个单例对象。

    2. 同时在 Component 类标明@Singleton,表明该 Component 中有 Module 使用了@Singleton。

public class UserBean {
    private String name;
​
    public UserBean(String name) {
        this.name = name;
    }
}
@Module
public class UserModule {
    @Singleton
    @Provides
    UserBean providesUserA() {
        return new UserBean("Lucas");
    }
}

如果 moudule 所依赖的 Comonent 中有被@Singleton 单例的对象,那么 Conponnent 也必须是单例的@Singleton,表明该 Component 中有 Module 使用了@Singleton

@Component(modules = UserModule.class)
@Singleton
public interface UserComponent {
    void inject(MainActivity mainActivity);
    void inject(SenActivity senActivity);
}
public class MainActivity extends AppCompatActivity {
    @Inject
    UserBean userBeanA;
    @Inject
    UserBean userBeanB;
    @Inject
    UserBean userBeanC;
​
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerUserComponent.create().inject(this);
​
        Logger.addLogAdapter(new AndroidLogAdapter());
        Logger.d(userBeanA);
        Logger.d(userBeanB);
        Logger.d(userBeanC);
    }
}
public class SenActivity extends Activity {
    @Inject
    UserBean userBean;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DaggerUserComponent.create().inject(this);
​
        Logger.addLogAdapter(new AndroidLogAdapter());
        Logger.d(userBean);
    }
}
  1. 自定义@scope实现局部单例

@Scope
@Documented
@Retention(RUNTIME)
public @interface UserScope {}
public class UserBean {
    private String name;
​
    public UserBean(String name) {
        this.name = name;
    }
}
@Module
public class UserModule {
    @UserScope
    @Provides
    UserBean providesUserA() {
        return new UserBean("Lucas");
    }
}
@Component(modules = UserModule.class)
@UserScope
public interface UserComponent {
    void inject(MainActivity mainActivity);
    void inject(SenActivity senActivity);
}
public class MainActivity extends AppCompatActivity {
    @Inject
    UserBean userBeanA;
    @Inject
    UserBean userBeanB;
    @Inject
    UserBean userBeanC;
​
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerUserComponent.create().inject(this);
​
        Logger.addLogAdapter(new AndroidLogAdapter());
        Logger.d(userBeanA);
        Logger.d(userBeanB);
        Logger.d(userBeanC);
    }
}
public class SenActivity extends Activity {
    @Inject
    UserBean userBean;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DaggerUserComponent.create().inject(this);
​
        Logger.addLogAdapter(new AndroidLogAdapter());
        Logger.d(userBean);
    }
}
  1. 全局单例

@Module
public class BaseModule {
    private final Context context;
​
    public BaseModule(Context context) {
        this.context = context;
    }
​
    @Provides
    @Singleton
    public SharedPreferences getSharedPreferences() {
        return context.getSharedPreferences("", Context.MODE_PRIVATE);
    }
}
@Component(modules = BaseModule.class)
@Singleton
public interface BaseComponent {
    void injectSharedPreferences(MainActivity activity);
    void injectSharedPreferences(SendActivity activity);
}
public class App extends Application {
    BaseComponent baseComponent;
​
    @Override
    public void onCreate() {
        super.onCreate();
        Logger.addLogAdapter(new AndroidLogAdapter());
        baseComponent = DaggerBaseComponent.builder().baseModule(new BaseModule(this)).build();
    }
}
public class MainActivity extends AppCompatActivity {
    @Inject
    SharedPreferences sf;
​
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ((com.angel.myapplication2.App) getApplication()).baseComponent.injectSharedPreferences(this);
        Logger.d(sf);
    }
}
public class SendActivity extends AppCompatActivity {
    @Inject
    SharedPreferences sf;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_send);
        ((App) getApplication()).baseComponent.injectSharedPreferences(this);
        Logger.d(sf);
    }
}

8.组件依赖

@Module
public class BaseModule {
    private  Context context;
​
    public BaseModule(Context context){
        this.context =context;
    }
    @Singleton
    @Provides
    SharedPreferences providesSharedPreferences() {
        return context.getSharedPreferences("fff", Context.MODE_PRIVATE);
    }
}
@Singleton
@Component(modules = BaseModule.class)
public interface BaseComponent {
     SharedPreferences getSF();
}
public class UserBean {
    private String name;
​
    public UserBean(String name) {
        this.name = name;
    }
​
    public UserBean() {
    }
}
@Module
public class UserModule {
    @UserScope
    @Provides
    UserBean providesUserA() {
        return new UserBean("Lucas");
    }
}
@Component(modules = UserModule.class,dependencies = BaseComponent.class)
@UserScope
public interface UserComponent {
    void inject(MainActivity mainActivity);
    void inject(SenActivity senActivity);
}
public class App extends Application {
    private BaseComponent baseComponent;
​
    @Override
    public void onCreate() {
        super.onCreate();
        baseComponent = DaggerBaseComponent.builder().baseModule(new BaseModule(this)).build();
        Logger.addLogAdapter(new AndroidLogAdapter());
    }
​
    public BaseComponent getBaseComponent() {
        return baseComponent;
    }
}
public class MainActivity extends AppCompatActivity {
​
    @Inject
    UserBean userBeanA;
    @Inject
    UserBean userBeanB;
    @Inject
    UserBean userBeanC;
    @Inject
    SharedPreferences sharedPreferences;
​
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerUserComponent.builder().baseComponent(((App) getApplication()).getBaseComponent()).build().inject(this);
​
        Logger.d(userBeanA);
        Logger.d(userBeanB);
        Logger.d(userBeanC);
        Logger.d(sharedPreferences);
    }
}
public class SenActivity extends Activity {
​
    @Inject
    UserBean userBean;
    @Inject
    SharedPreferences sharedPreferences;
​
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DaggerUserComponent.builder().baseComponent(((App) getApplication()).getBaseComponent()).build().inject(this);
        Logger.d(userBean);
        Logger.d(sharedPreferences);
    }
  1. 懒加载Lazy<T>,高性能的重要举措之一:在需要的时候才对成员变量进行初始化,可以大幅缩短应用初始化的时间。

    使用方法:用 Lazy<T>修饰变量即可。Lazy 是泛型类,接受任何类型的参数。

    public class Logger {
        private String name;
    ​
        public Logger(String name) {
            this.name = name;
        }
    ​
        public String getName() {
            return name;
        }
    }
    @Module
    public class LogModule {
        @Named("aaa")
        @Singleton
        @Provides
        public Logger providerLogger() {
            return new Logger("aaaa");
        }
    ​
        @Named("bbb")
        @Singleton
        @Provides
        public Logger providerLoggerB() {
            return new Logger("bbbb");
        }
    }
    @Singleton
    @Component(modules = LogModule.class)
    public interface LogComponent {
        void inject(MainActivity activity);
    }
    public class MainActivity extends AppCompatActivity {
        @Inject
        @Named("aaa")
        Logger logger;
        @Inject
        @Named("bbb")
        Lazy<Logger> log;
    ​
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            DaggerLogComponent.create().inject(this);
            com.orhanobut.logger.Logger.addLogAdapter(new AndroidLogAdapter());
            com.orhanobut.logger.Logger.d(logger.getName());
            com.orhanobut.logger.Logger.d(log.get());
            com.orhanobut.logger.Logger.d(log.get().getName());
        }
    }
  2. Provider 强制重新加载,我们希望每次都创建一个新的实例,这种情况与 @Singleton 完全相反。

public class Logger {
    private String name;
​
    public Logger(String name) {
        this.name = name;
    }
​
    public String getName() {
        return name;
    }
}
@Module
public class LogModule {
    @Named("aaa")
    @Provides
    public Logger providerLogger() {
        return new Logger("aaaa");
    }
​
    @Named("bbb")
    @Provides
    public Logger providerLoggerB() {
        return new Logger("bbbb");
    }
}
@Component(modules = LogModule.class)
public interface LogComponent {
    void inject(MainActivity activity);
}
public class MainActivity extends AppCompatActivity {
    @Inject
    @Named("aaa")
    Logger logger;
​
    @Inject
    @Named("bbb")
    Provider<Logger> log;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerLogComponent.create().inject(this);
        com.orhanobut.logger.Logger.addLogAdapter(new AndroidLogAdapter());
        com.orhanobut.logger.Logger.d(logger);
        com.orhanobut.logger.Logger.d(log.get());
        com.orhanobut.logger.Logger.d(log.get());
    }
}
  1. @subComponent

@Module
public class BaseModule {
    private  Context context;
​
    public BaseModule(Context context){
        this.context =context;
    }
    @Singleton
    @Provides
    SharedPreferences providesSharedPreferences() {
        return context.getSharedPreferences("fff", Context.MODE_PRIVATE);
    }
}
@Singleton
@Component(modules = BaseModule.class)
public interface BaseComponent {
     SharedPreferences getSF();
​
     UserComponent provideUserComponent();
}
public class UserBean {
    private String name;
​
    public UserBean(String name, SharedPreferences sp) {
        this.name = name;
        Logger.d(sp);
    }
}
@Module
public class UserModule {
​
    @Named("A")
    @UserScope
    @Provides
    UserBean providesUserA(SharedPreferences sp) {
        return new UserBean("Lucas",sp);
    }
​
    @Named("B")
    @UserScope
    @Provides
    UserBean providesUserB(SharedPreferences sp) {
        return new UserBean("ABC",sp);
    }
}
@Subcomponent(modules = UserModule.class)
@UserScope
public interface UserComponent {
    void inject(MainActivity mainActivity);
}
@Scope
@Documented
@Retention(RUNTIME)
public @interface UserScope {}
public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Logger.addLogAdapter(new AndroidLogAdapter());
    }
}
public class MainActivity extends AppCompatActivity {
​
    @Named("A")
    @Inject
    UserBean userBeanA;
    @Named("A")
    @Inject
    UserBean userBeanB;
    @Inject
    @Named("B")
    UserBean userBeanC;
    @Inject
    SharedPreferences sharedPreferences;
​
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerBaseComponent.builder().baseModule(new BaseModule(this)).build()
                .provideUserComponent().inject(this);
        Logger.d(userBeanA);
        Logger.d(userBeanB);
        Logger.d(userBeanC);
        Logger.d(sharedPreferences);
    }
}

添加Dagger2依赖

<dependency>
            <groupId>com.google.dagger</groupId>
            <artifactId>dagger</artifactId>
            <version>2.35</version>
        </dependency>
​
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>com.google.dagger</groupId>
                            <artifactId>dagger-compiler</artifactId>
                            <version>2.35</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡恩_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值