美文网首页
Dagger 作用域Singleton

Dagger 作用域Singleton

作者: coke613 | 来源:发表于2023-07-17 09:59 被阅读0次

先看代码

public  interface Api {
    @POST("/api/sdk/v1/init")
    Call<String> login();
}

// 声明Module

@Module
public class NetWorkModule {
    @Provides
    public Retrofit provideRetrofit(){
        return new Retrofit.Builder()
                .baseUrl("https://www.google.com")
                .build();
    }


    @Provides
    public Api providesApi(Retrofit retrofit){
        return retrofit.create(Api.class);
    }

}

// 将Module 装到Component 容器中

@Component(modules = NetWorkModule.class)
public interface ApplicationCommponent {
    void inject(TextDaggerActivity mainActivity);
}
public class TextDaggerActivity extends AppCompatActivity {


   @Inject
   Retrofit retrofit1;

   @Inject
   Retrofit retrofit2;

   @Override
   protected void onCreate(@Nullable Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      DaggerApplicationCommponent.create(). inject(this);

      Log.e("retrofit1----","address: "+retrofit1);
      Log.e("retrofit2----","address: "+retrofit2);
   }
}
 打印结果:
E/retrofit1----: address: retrofit2.Retrofit@5707fc6
E/retrofit2----: address: retrofit2.Retrofit@f8eb87

在项目开发中, Retrofit 应该是全局的,单一的.
那如何修改呢?

修改 NetWorkModule , 在具备单一性的函数上添加 @Singleton 注解.

@Module
public class NetWorkModule {
    @Provides
    @Singleton
    public Retrofit provideRetrofit(){
        return new Retrofit.Builder()
                .baseUrl("https://www.google.com")
                .build();
    }  
    @Singleton  
    @Provides
    public Api providesApi(Retrofit retrofit){
        return retrofit.create(Api.class);
    }

}

同时,在Component 容器上也要添加 @Singleton 注解.


@Singleton
@Component(modules = NetWorkModule.class)
public interface ApplicationCommponent {
    void inject(TextDaggerActivity mainActivity);

}

此时,再次运行代码.

打印结果: 
E/retrofit1----: address: retrofit2.Retrofit@5707fc6
E/retrofit2----: address: retrofit2.Retrofit@5707fc6

如此,看样子确实是实现了单例模式.

创建TextDaggerActivity2.class. 同时修改ApplicationCommponent.

@Singleton
@Component(modules = NetWorkModule.class)
public interface ApplicationCommponent {
    void inject(TextDaggerActivity mainActivity);
    void inject(TextDaggerActivity2 mainActivity);

}
public class TextDaggerActivity extends AppCompatActivity {
    ...
    @Override
   protected void onCreate(@Nullable Bundle savedInstanceState) {
        ...

       startActivity(new Intent(this,TextDaggerActivity2.class));
   }
 
}
public class TextDaggerActivity2 extends AppCompatActivity {

   @Inject
   Retrofit retrofit;

   @Override
   protected void onCreate(@Nullable Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      DaggerApplicationCommponent.create(). inject(this);
      Log.e("retrofit3----","address: "+retrofit);
   }
}

两个Activity 都声明了Retrofit, 并使用@Inject 注入. 看一下执行结果

打印结果: 
E/retrofit1----: address: retrofit2.Retrofit@5707fc6
E/retrofit2----: address: retrofit2.Retrofit@5707fc6
E/retrofit3----: address: retrofit2.Retrofit@48b72b9

可见Dagger 中的@Singleton注解并不是真正意义上的单例模式。而是局部单例模式.

在Dagger 中,@Singleton注解用于标记一个对象的作用域范围,表示在同一个作用域内只会创建一个对象实例,但它不能保证对象的唯一性.

拿到代码上来说, 被@Singleton 修饰的容器,它们的作用域一个在TextDaggerActivity, 另一个在TextDaggerActivity2 进行create(), 两个是不同的作用域的,所以也就导致了局部单例.

如何实现真正意义上的单例呢?
自定义Application, 被@Singleton 修饰的容器作用域指定为全局.

public class App extends Application {

   public static ApplicationCommponent applicationCommponent;

   @Override
   public void onCreate() {
      super.onCreate();
      applicationCommponent = DaggerApplicationCommponent.create();
   }
}

// TextDaggerActivity  & TextDaggerActivity2 修改为:
App.applicationCommponent.injectUser(this);

此时,再次运行代码.

打印结果: 
E/retrofit1----: address: retrofit2.Retrofit@5707fc6
E/retrofit2----: address: retrofit2.Retrofit@5707fc6
E/retrofit3----: address: retrofit2.Retrofit@5707fc6

总结 :

Dagger中的@Singleton注解并不是真正意义上的单例模式。在Dagger中,@Singleton注解用于标记一个对象的作用域范围,表示在同一个作用域内只会创建一个对象实例,但它并不能保证这个对象的唯一性.

相关文章

  • Spring中的Bean<3>

    作用域: singleton:单例模式,在整个Spring ioc容器中,singleton作用域的bean将只生...

  • Bean的作用域

    Bean的作用域: singleton 当一个bean的作用域为singleton,那么Spring IoC容器中...

  • Bean的作用域

    Bean的作用域: singleton 当一个bean的作用域为singleton,那么Spring IoC容器中...

  • spring scope prototype与singleton

    1、singleton作用域当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存...

  • spring详解(二)

    ③容器中bean的作用域: |作用域|描述||---|---||singleton|单例模式,在整个Spring ...

  • Spring

    Spring Bean 作用域 Spring 3 中为 Bean 定义了 5 中作用域分别为 singleton(...

  • Spring Bean的生命周期

    Spring 容器可以管理 singleton 作用域 Bean 的生命周期,在此作用域下,Spring 能够精确...

  • 说说在 Spring 中如何注入或替换方法

    无状态 Bean 的作用域是 singleton 单实例,如果我们向 singleton 的 Bean A 注入 ...

  • Spring笔记(二):bean的作用域

    在bean中配置作用域使用属性scope来设置bean的作用域 scope="singleton" 也是bean配...

  • Spring中Bean的作用域

    作用域类型 1.singleton 2.prototype 注: 以下三个作用域只能在WebApplication...

网友评论

      本文标题:Dagger 作用域Singleton

      本文链接:https://www.haomeiwen.com/subject/dxrwudtx.html