Dagger 2——有构造函数对象的依赖注入使用方法

105 阅读2分钟

一、对有构造函数的依赖注入涉及到如下内容:

  1. @Inject
  2. @Component
  3. @Inject@Component 协同作战。

二、问题背景

在介绍他们之前我们来看一段我们在项目中看到的类似的代码:

public class ClassA{
    ClassB classB = new ClassB();
    ClassC classC = new ClassC("xxx",xxx);
    .....
}

当我们在目标类初始化其他类时,这些工作几乎都是重复性的操作,而且有强耦合性,所以需要一种方案来替代这种写法

三、依赖注入方案

@Inject

@Inject为了实现以上功能,我们需要完成以下步骤:

需要用注解 @Inject (Annotation) 来标注目标类中依赖类的实例对象
同样用注解 @Inject (Annotation) 来标注所依赖的其他类的 构造函数。

目标类 ClassA

	    public class ClassA{
	    
	        @Inject
	        ClassB classB;// 使用 @Inject 标注依赖类的实例对象
	        
	        @Inject
	        ClassC classC;
       
	    }

依赖类 ClassB

    public class ClassB{
        @Inject // 使用 @Inject 标注依赖类的构造函数
        public ClassB(){}
        ....
    }

依赖类 ClassC

    public class ClassC{
        @Inject
        public ClassC(XXX xxx, XXX xxx){
            ...
        }
    }

注意:在使用 @Inject 标注类的构造函数,只能标注一个构造函数,无法标注多个。 虽然 目标类 和 依赖类 都使用了@Inject 来标记,但是他们并没有产生实在意义上的联系,这时 @Component 就充当了媒婆的角色。

@Component

作用:将 Module 中产生的依赖对象自动注入到需要依赖实例的 Container中

从上面的描述中我们可以看到 Component 充当了 Module 和 Container 的媒介。

很明显 @Component 是一个注解,那么被 @Component 标记的类理所当然的被称为 注解类,并且该类必须是接口或抽象类。那么下面我们看一下这个媒婆是怎么开展工作的:

  1. @Component 标注类的实例必须存在目标类中
  2. Component会查找目标类中用 @Inject 注解标注的属性
  3. 查找到相应的属性后,会接着查找该属性对应的用 @Inject 标注的构造函数(这时候就发生联系了)
  4. 剩下的工作就是初始化该属性的实例并把实例进行赋值

图片.png

四、案例

public class User {
    private String mName = "xing mo";
    private int mAge = 18;
    @Inject
    public User() { }

    public String getName() {
        return mName;
    }

    public void setName(String mName) {
        this.mName = mName;
    }

    public int getAge() {
        return mAge;
    }

    public void setAge(int mAge) {
        this.mAge = mAge;
    }
}
@Component
public interface UserComponent {
    void inject(MainActivity mMainActivity);
}
public class MainActivity extends AppCompatActivity {

    @Inject
    User mUser;

    private static final String TAG = "MainActivity";

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


        // 这一句代码是完成依赖注入的关键
        DaggerUserComponent.builder().build().inject(this);
        
        Log.e(TAG,"name : " + mUser.getName() + " age :" + mUser.getAge());
        mUser.setAge(60);
        mUser.setName("test");
        Log.e(TAG,"name2 : " + mUser.getName() + " age2 :" + mUser.getAge());


    }
}

注:DaggerUserComponent 是编译之后产生的,需要build之后导入即可