研究了下dagger2,现在结合dagger2生成的代码分析下。
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0213/2478.html 比较全面
apply plugin: 'com.neenbedankt.android-apt'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}
}
android {
...
}
dependencies {
apt 'com.google.dagger:dagger-compiler:2.0.2'
compile 'com.google.dagger:dagger:2.0.2'
provided 'javax.annotation:jsr250-api:1.0'
}
Component
被Component标注的接口。这里是连接注入实例与被注入实例的桥梁。
@Component
public interface ApplicationComponent {
}
成功编译时自动生成一个实现类Dagger***实现我们定义的接口。
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerApplicationComponent implements ApplicationComponent {
private DaggerApplicationComponent(Builder builder) {
assert builder != null;
}
public static Builder builder() {
return new Builder();
}
public static ApplicationComponent create() {
return builder().build();
}
public static final class Builder {
private Builder() {
}
public ApplicationComponent build() {
return new DaggerApplicationComponent(this);
}
}
}
这个实现类内部有一个静态不可被继承的内部类Builder。可以通过Dagger.create()获取到该实现类的实例,也可以通过Dagger.builder.build()获取。
显然这样的实现类并没有什么卵用,要将我们需要注入的对象与被注入对象联系起来则需要在conponent接口中写一个返回值为void的方法。
@Component
public interface ApplicationComponent {
void inject(MyApp app);
}
生成的代码
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerApplicationComponent implements ApplicationComponent {
private DaggerApplicationComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static ApplicationComponent create() {
return builder().build();
}
private void initialize(final Builder builder) {
}
@Override
public void inject(MyApp app) {
MembersInjectors.noOp().injectMembers(app);
}
public static final class Builder {
private Builder() {
}
public ApplicationComponent build() {
return new DaggerApplicationComponent(this);
}
}
}
可以看到生成的代码中有个方法。内部实现都是MembersInjectors.noOp().injectMembers(app),这个MembersInjectors又是什么。
public final class MembersInjectors {
@SuppressWarnings("unchecked")
public static MembersInjector noOp() {
return (MembersInjector) NoOpMembersInjector.INSTANCE;
}
private static enum NoOpMembersInjector implements MembersInjector
injectMembers()这个方法只是对参数进行了非空判断,这个方法似乎也是什么卵用没有。
在看我们定义的接口里的方法inject(MyApp app),参数app只是被注入的对象,注入的对象在哪里传入?这就需要写在被注入的对象里了。
public class MyApp extends Application {
@Inject
User user;
@Override
public void onCreate() {
super.onCreate();
DaggerApplicationComponent.create().inject(this);
}
}
在被注入的对象里创建成员变量,用Inject标注。再编译之后。
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerApplicationComponent implements ApplicationComponent {
private MembersInjector myAppMembersInjector;
private DaggerApplicationComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static ApplicationComponent create() {
return builder().build();
}
private void initialize(final Builder builder) {
this.myAppMembersInjector = MyApp_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), User_Factory.create());
}
@Override
public void inject(MyApp app) {
myAppMembersInjector.injectMembers(app);
}
public static final class Builder {
private Builder() {
}
public ApplicationComponent build() {
return new DaggerApplicationComponent(this);
}
}
}
Dagger的inject方法里是myAppMembersInjector.injectMembers(app),好像嗯刚才的MembersInjector.injectMembers()不一样。追进代码到MyApp_MembersInjector 。这个也是编译时创建的类。
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class MyApp_MembersInjector implements MembersInjector {
private final MembersInjector supertypeInjector;
private final Provider userProvider;
public MyApp_MembersInjector(MembersInjector supertypeInjector, Provider userProvider) {
assert supertypeInjector != null;
this.supertypeInjector = supertypeInjector;
assert userProvider != null;
this.userProvider = userProvider;
}
@Override
public void injectMembers(MyApp instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
supertypeInjector.injectMembers(instance);
instance.user = userProvider.get();
}
public static MembersInjector create(MembersInjector supertypeInjector, Provider userProvider) {
return new MyApp_MembersInjector(supertypeInjector, userProvider);
}
}
看它的injectMembers()方法,先调用了supertypeInjector.injectMembers(instance),再将userProvider.get()的返回值赋值给被注入对象app的user变量。
追进userProviders.get()方法。
@Generated("dagger.internal.codegen.ComponentProcessor")
public enum User_Factory implements Factory {
INSTANCE;
@Override
public User get() {
return new User();
}
public static Factory create() {
return INSTANCE;
}
}
方法内部实际是创建了一个对象返回。至此,就可以明白被注入的实例是怎样注入到参数中的。supertypeInjector.injectMembers(instance)是递归将父类需要注入的实例注入参数中。User对象的构造方法需要且只能有一个被Inject标注,否则会报错。
public class User {
@Inject
public User(){
}
}
在需要的地方通过DaggerApplicationComponent.create().inject(this)就可以将需要注入的实例注入到被注入对象中。