20210703 - 架构 - IOC注入神器dagger2详解

20210703 - 架构 - IOC注入神器dagger2详解

IOC(Inversion of Control)

是原来由程序代码中主动获取的资源,转变由第三方获取并使原来的代码被动接收的方式,以达到解耦的效果,称为控制反转

基本配置

implementation 'com.google.dagger:dagger:2.4'
annotationProcessor 'com.google.dagger:dagger-compiler:2.4'

使用逻辑

  • module: 用于提供对象

  • component: 用于组织module并进行注入

基本使用

// 1.提供用于注入的对象
public class HttpClient {
}
public class ImClient {
}

// 2.编写Module
@Module
public class HttpModule {
    @Provides
    public HttpClient provideHttpClient(){
        return new HttpClient();
    }
}
@Module
public class ImModule {
    @Provides
    public ImClient provideImClient(){
        return new ImClient();
    }
}

// 3.编写Component
@Component(modules = {HttpModule.class, ImModule.class})
public interface MainComponent {
    void injectMainActivity(MainActivity mainActivity);
}

// 4.注入到Activity
// 5.rebuild项目让APT生成需要的文件 
// 6.在需要注入的类中使用
public class MainActivity extends AppCompatActivity {
    @Inject
    HttpClient httpClient;
    
    @Inject
    ImClient imClient;

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //1.语法1
        DaggerMainComponent.create().injectMainActivity(this);
        //2.语法2
        DaggerMainComponent.builder()
                .httpModule(new HttpModule())
                .imModule(new ImModule())
                .build()
                .injectMainActivity(this);
	}
}

单例使用

// 1、该单例只能在注入类中局部有效
// 2、如果要实现局部单例,那么就要在 Component、Module 中都要标记 @Singleton
// 3、建议用自定义 Scope 注解(如@AppScope、@UserScope),来代替 @Singleton 实现局部单例

// --- 不建议的局部单例 ---
@Singleton
@Module
public class ImModule {
    @Singleton
    @Provides
    public ImClient provideImClient(){
        return new ImClient();
    }
}

@Singleton
@Component(modules = {HttpModule.class, ImModule.class})
public interface MainComponent {
    void injectMainActivity(MainActivity mainActivity);
}

// --- 推荐的局部单例 ---
@Scope
@Documented
@Retention(RUNTIME)
public @interface MainScope {
}

@MainScope
@Module
public class ImModule {
    @MainScope
    @Provides
    public ImClient provideImClient(){
        return new ImClient();
    }
}

@MainScope
@Component(modules = {HttpModule.class, ImModule.class})
public interface MainComponent {
    void injectMainActivity(MainActivity mainActivity);
}

// --- 全局单例 ---
public class MyApplication extends Application {
    private MainComponent mainComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        mainComponent = DaggerMainComponent.create();
    }

    public MainComponent getMainComponent() {
        return mainComponent;
    }
}

多个Component组合依赖

方式一:dependencies用法

// 1.Scope
@Scope
@Documented
@Retention(RUNTIME)
public @interface DbScope {
}

// 2. module
public class DbClient {
}

@DbScope
@Module
public class DbModule {
    @DbScope
    @Provides
    public DbClient provideDbClient(){
        return new DbClient();
    }
}

// 3. component
@DbScope
@Component(modules = {DbModule.class})
public interface DbComponent {
    DbClient provideDbClient();
}

@MainScope
@Component(modules = {HttpModule.class, ImModule.class}, dependencies = {DbComponent.class})
public interface MainComponent {
    void injectMainActivity(MainActivity mainActivity);
}

// 4. 使用
public class MainActivity extends AppCompatActivity {
    @Inject
    HttpClient httpClient;

    @Inject
    ImClient imClient;

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

        DaggerMainComponent.builder()
                .httpModule(new HttpModule())
                .imModule(new ImModule())
                .dbComponent(DaggerDbComponent.create())
                .build()
                .injectMainActivity(this);

        Log.d("xiaowang", httpClient.hashCode() + "");
        Log.d("xiaowang", imClient.hashCode() + "");
        Log.d("xiaowang", dbClient.hashCode() + "");
    }
}
// dependencies注意事项:
// 		1) 多个 component 上面的 scope 不能相同
// 		2) 没有 scope 的组件不能去依赖有 scope 的组件

方式二:@Subcomponent用法

@DbScope
@Subcomponent(modules = {DbModule.class})
public interface DbComponent {
    void injectMainActivity(MainActivity mainActivity);
}

@MainScope
@Component(modules = {HttpModule.class, ImModule.class})
public interface MainComponent {
    DbComponent getDbComponent();
}

DaggerMainComponent.create()
        .getDbComponent()
        .injectMainActivity(this);

其它用法

带参数module

@Module
public class MainModule {
    @Provides
    B providerB() {
        return new B();
    }

	// 构造方法需要其他参数时候,dagger2会自动把参数传入,并构造
    @Provides
    A providerA(B b) {
        return new A(b);
    }
}

@Named使用

// ------- module中 -------
@Named("key1")
@Provides
public User provideUser(){
	return new User("jett","123")}

@Named("key2")
@Provides
public User provideUser2(){
	return new User("jett2","456")}

// ------- Activity中 -------
@Named("key1")
@Inject
User user1;

@Named("key2")
@Inject 
User user2;

// 通过以上语法,就可以实现两个不同的 key 注入不一样的同类型对象

Lazy 和 Provider

这种方式是在get的时候,才初始化需要注入的对象

// ------ 懒加载(具备局部单例特点)------
@Inject
Lazy<A> lazy;

@Inject
Lazy<A> lazy2;

Log.i("icoTag", lazy.get().hashCode() + "");// 43536281
Log.i("icoTag", lazy2.get().hashCode() + "");// 43536281

// ------ 懒加载(不具备局部单例特点)------
@Inject
Provider<A> provider;

@Inject
Provider<A> provider2;

Log.i("icoTag", provider.get().hashCode() + "");// 208712286
Log.i("icoTag", provider2.get().hashCode() + "");// 84461119
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring-IOC是Spring框架的核心部分之一,它是一种设计模式,全称为Inversion of Control(控制反转)。它通过将对象的创建、依赖关系的管理和对象的生命周期交给Spring容器来实现,从而降低了组件之间的耦合度,提高了代码的可重用性和可维护性。Spring-IOC的实现主要依靠Spring容器,Spring容器是Spring框架的核心,它负责创建、管理和装配Bean对象,其中Bean是Spring框架中最基本的组件。 Spring-IOC的实现主要有两种方式:BeanFactory和ApplicationContext。其中,BeanFactory是Spring-IOC的基本实现,而ApplicationContext是BeanFactory的子接口,提供了更多高级特性。ApplicationContext是Spring框架中最常用的IOC容器,它除了提供BeanFactory的所有功能外,还提供了更多的企业级特性,例如AOP、事务管理、国际化、事件传播等。 下面是一个简单的Spring-IOC的例子,假设我们有一个UserService接口和一个UserServiceImpl实现类,我们可以通过Spring-IOC容器来创建和管理UserServiceImpl对象: 1.定义UserService接口和UserServiceImpl实现类 ```java public interface UserService { void addUser(User user); } @Service public class UserServiceImpl implements UserService { @Override public void addUser(User user) { // 添加用户的具体实现 } } ``` 2.在Spring配置文件中配置UserService实例 ```xml <bean id="userService" class="com.example.service.UserServiceImpl"/> ``` 3.在代码中获取UserService实例并使用 ```java ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = context.getBean("userService", UserService.class); User user = new User(); userService.addUser(user); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值