先看Dagger2的注解
image
1.Inject注解
- 作用在构造方法上
//空参构造
public class PersonBean {
String name;
@Inject
public PersonBean() {
}
}
//生成的工厂类
public final class PersonBean_Factory implements Factory<PersonBean> {
private static final PersonBean_Factory INSTANCE = new PersonBean_Factory();
@Override
public PersonBean get() {
return new PersonBean();
}
public static Factory<PersonBean> create() {
return INSTANCE;
}
}
//有参构造
public class PersonBean {
String name;
@Inject
public PersonBean(String name) {
this.name = name;
}
}
生成的工厂类
public final class PersonBean_Factory implements Factory<PersonBean> {
private final Provider<String> nameProvider;
public PersonBean_Factory(Provider<String> nameProvider) {
assert nameProvider != null;
this.nameProvider = nameProvider;
}
@Override
public PersonBean get() {
return new PersonBean(nameProvider.get());
}
public static Factory<PersonBean> create(Provider<String> nameProvider) {
return new PersonBean_Factory(nameProvider);
}
}
- 作用在字段上
// 在person类中注入变量
public class Clothes {
String color;
@Inject
public Clothes(String color) {
this.color = color;
}
}
public class PersonBean {
String name;
@Inject
Clothes clothes;
@Inject
public PersonBean(String name) {
this.name = name;
}
}
此时在apt目录下多生成了一个PersonBean_MembersInjector文件,如图:
dagger_1.PNG
public final class PersonBean_MembersInjector implements MembersInjector<PersonBean> {
private final Provider<Clothes> clothesProvider;
public PersonBean_MembersInjector(Provider<Clothes> clothesProvider) {
assert clothesProvider != null;
this.clothesProvider = clothesProvider;
}
public static MembersInjector<PersonBean> create(Provider<Clothes> clothesProvider) {
return new PersonBean_MembersInjector(clothesProvider);
}
@Override
public void injectMembers(PersonBean instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.clothes = clothesProvider.get();
}
public static void injectClothes(PersonBean instance, Provider<Clothes> clothesProvider) {
instance.clothes = clothesProvider.get();
}
}
apt插件为PersonBean生成了一个成员注入类,该类提供了PersonBean需要的Clothes实例。PersonBean_Factory也改变成了如下结构:
public final class PersonBean_Factory implements Factory<PersonBean> {
private final MembersInjector<PersonBean> personBeanMembersInjector;
private final Provider<String> nameProvider;
public PersonBean_Factory(
MembersInjector<PersonBean> personBeanMembersInjector, Provider<String> nameProvider) {
assert personBeanMembersInjector != null;
this.personBeanMembersInjector = personBeanMembersInjector;
assert nameProvider != null;
this.nameProvider = nameProvider;
}
@Override
public PersonBean get() {
return MembersInjectors.injectMembers(
personBeanMembersInjector, new PersonBean(nameProvider.get()));
}
public static Factory<PersonBean> create(
MembersInjector<PersonBean> personBeanMembersInjector, Provider<String> nameProvider) {
return new PersonBean_Factory(personBeanMembersInjector, nameProvider);
}
}
2.Component注解
@Component
public interface DemoComponent {
Student student();
}
apt会为该注解生成一个工厂类:
public final class DaggerDemoComponent implements DemoComponent {
private DaggerDemoComponent(Builder builder) {
assert builder != null;
}
public static Builder builder() {
return new Builder();
}
public static DemoComponent create() {
return new Builder().build();
}
@Override
public Student student() {
return new Student();
}
public static final class Builder {
private Builder() {}
public DemoComponent build() {
return new DaggerDemoComponent(this);
}
}
}
在Component里面添加的抽象方法,会在对应的DaggerDemoComponent类中进行实现。
3.Provider注解和Module注解
@Module
public class OneModule {
@Provides
public Clothes provideClothes() {
return new Clothes("紫色");
}
@Provides
public PersonBean providePersonBean() {
return new PersonBean("大西瓜");
}
}
会生成模块名+方法名+Factory的工程类(OneModule_ProvidePersonBeanFactory)。
注意:
1.模块必须要使用Module注解修饰。
2.Module中的方法需要provider开头,否则生成的文件会报错。
public final class OneModule_ProvidePersonBeanFactory implements Factory<PersonBean> {
private final OneModule module;
public OneModule_ProvidePersonBeanFactory(OneModule module) {
assert module != null;
this.module = module;
}
@Override
public PersonBean get() {
return Preconditions.checkNotNull(
module.providePersonBean(), "Cannot return null from a non-@Nullable @Provides method");
}
public static Factory<PersonBean> create(OneModule module) {
return new OneModule_ProvidePersonBeanFactory(module);
}
}
public final class OneModule_ProvideClothesFactory implements Factory<Clothes> {
private final OneModule module;
public OneModule_ProvideClothesFactory(OneModule module) {
assert module != null;
this.module = module;
}
@Override
public Clothes get() {
return Preconditions.checkNotNull(
module.provideClothes(), "Cannot return null from a non-@Nullable @Provides method");
}
public static Factory<Clothes> create(OneModule module) {
return new OneModule_ProvideClothesFactory(module);
}
}
4.Singleton注解
@Singleton
@Component(modules = {OneModule.class})
public interface DemoComponent {
void inject(MainActivity activity);
Student student();
}
为Component提供Singleton注解,在apt生成的代码中,会进行DoubleCheck的检查,保证单例。
private void initialize(final Builder builder) {
this.provideXiguaPersonBeanProvider =
DoubleCheck.provider(OneModule_ProvideXiguaPersonBeanFactory.create(builder.oneModule));
this.mainActivityMembersInjector =
MainActivity_MembersInjector.create(provideXiguaPersonBeanProvider);
this.studentProvider = DoubleCheck.provider(Student_Factory.create());
}
二、让组件(Component)依赖Module
@Component(modules = {OneModule.class})
public interface DemoComponent {
Student student();
}
在DaggerDemoComponent中的Buider对象中生成oneModule(OneModule oneModule)方法。
public final class DaggerDemoComponent implements DemoComponent {
private DaggerDemoComponent(Builder builder) {
assert builder != null;
}
public static Builder builder() {
return new Builder();
}
public static DemoComponent create() {
return new Builder().build();
}
@Override
public Student student() {
return new Student();
}
public static final class Builder {
private Builder() {}
public DemoComponent build() {
return new DaggerDemoComponent(this);
}
/**
* @deprecated This module is declared, but an instance is not used in the component. This
* method is a no-op. For more, see https://google.github.io/dagger/unused-modules.
*/
@Deprecated
public Builder oneModule(OneModule oneModule) {
Preconditions.checkNotNull(oneModule);
return this;
}
}
}
在Activity中注入对象
public class MainActivity extends AppCompatActivity {
@Inject
PersonBean personBean;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerDemoComponent.builder()
.oneModule(new OneModule())
.build()
.inject(this);
}
}
注意:需要使用inject方法注入指定类。
在加入inject方法后,生成了如下方法。
1.在DaggerDemoComponent中找到所有@Inject修饰的需要注入的变量的provider,并且在build后对这些变量进行赋值。
2.在inject(this)的时候,会将已经赋值的变量找到
MainActivity_MembersInjector(注入类+MembersInjector)中真正的变量进行赋值。
public final class DaggerDemoComponent implements DemoComponent {
private Provider<PersonBean> providePersonBeanProvider;
private MembersInjector<MainActivity> mainActivityMembersInjector;
private DaggerDemoComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static DemoComponent create() {
return new Builder().build();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.providePersonBeanProvider = OneModule_ProvidePersonBeanFactory.create(builder.oneModule);
this.mainActivityMembersInjector =
MainActivity_MembersInjector.create(providePersonBeanProvider);
}
@Override
public void inject(MainActivity activity) {
mainActivityMembersInjector.injectMembers(activity);
}
@Override
public Student student() {
return new Student();
}
public static final class Builder {
private OneModule oneModule;
private Builder() {}
public DemoComponent build() {
if (oneModule == null) {
this.oneModule = new OneModule();
}
return new DaggerDemoComponent(this);
}
public Builder oneModule(OneModule oneModule) {
this.oneModule = Preconditions.checkNotNull(oneModule);
return this;
}
}
}
public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
private final Provider<PersonBean> personBeanProvider;
public MainActivity_MembersInjector(Provider<PersonBean> personBeanProvider) {
assert personBeanProvider != null;
this.personBeanProvider = personBeanProvider;
}
public static MembersInjector<MainActivity> create(Provider<PersonBean> personBeanProvider) {
return new MainActivity_MembersInjector(personBeanProvider);
}
@Override
public void injectMembers(MainActivity instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.personBean = personBeanProvider.get();
}
public static void injectPersonBean(
MainActivity instance, Provider<PersonBean> personBeanProvider) {
instance.personBean = personBeanProvider.get();
}
}
三、其他的一些问题
- @Inject 和 @Provides 的优先级
Dagger2 依赖查找的顺序是先查找 Module 内所有的 @Provides 提供的依赖,如果查找不到再去查找 @Inject 提供的依赖。
网友评论