代碼示例
class Tiger {
public void sleep() {
System.out.println("Tiger sleeping");
}
}
@Module
class ZooModule {
@Singleton // 注意這裏
@Provides
public Tiger providerTiger() {
return new Tiger();
}
}
@Singleton // 注意這裏
@Component(modules = {ZooModule.class})
interface ZooComponent {
Zoo inject(Zoo zoo);
}
public class Zoo {
@Inject
Tiger tiger;
@Test
public void 案例八() {
DaggerZooComponent.create().inject(this);
tiger.sleep();
}
}
Dagger2生成代碼閱讀
主要分析加了
@Singleton
註解之後,Tiger
對象在同一個注射器生命週期中是一個單例對象.
就着上面的案例來看下Degger2生成的代碼,生成的代碼在build\generated\sources\annotationProcessor\..
文件夾中.
DaggerZooComponent.create()
final class DaggerZooComponent implements ZooComponent {
private Provider<Tiger> providerTigerProvider;
private DaggerZooComponent(ZooModule zooModuleParam) {
// 該方法最終創建一個Provider對象,它持有ZooModule_ProviderTigerFactory對象.
initialize(zooModuleParam);
}
private void initialize(final ZooModule zooModuleParam) {
// ZooModule_ProviderTigerFactory.create(zooModuleParam)創建一個ZooModule_ProviderTigerFactory對象,它的父類其實是Provider.
// DoubleCheck.provider():創建DoubleCheck對象.
this.providerTigerProvider = DoubleCheck.provider(ZooModule_ProviderTigerFactory.create(zooModuleParam));
}
static final class Builder {
private ZooModule zooModule;
private Builder() {
}
public Builder zooModule(ZooModule zooModule) {
this.zooModule = Preconditions.checkNotNull(zooModule);
return this;
}
// 創建注射器對象
public static ZooComponent create() {
return new Builder().build();
}
public ZooComponent build() {
if (zooModule == null) {
// ZooModule對象在這裏被創建
this.zooModule = new ZooModule();
}
// 創建注射器對象DaggerZooComponent.
return new DaggerZooComponent(zooModule);
}
}
}
- 注入對象前需要弄清除
DoubleCheck.provider()
首先看ZooModule_ProviderTigerFactory.create(zooModuleParam)
public final class ZooModule_ProviderTigerFactory implements Factory<Tiger> {
// 該方法主要用來創建ZooModule_ProviderTigerFactory對象,它的父類其實是Provider.
public static ZooModule_ProviderTigerFactory create(ZooModule module) {
return new ZooModule_ProviderTigerFactory(module);
}
}
再看下DoubleCheck.provider()
public final class DoubleCheck<T> implements Provider<T>, Lazy<T> {
public static <P extends Provider<T>, T> Provider<T> provider(P delegate) {
...
// delegate:是ZooModule_ProviderTigerFactory對象,他的父類是Provider.
return new DoubleCheck<T>(delegate);
}
// 它最終將ZooModule_ProviderTigerFactory對象存儲起來了.
private DoubleCheck(Provider<T> provider) {
assert provider != null;
this.provider = provider;
}
}
.inject(this)
final class DaggerZooComponent implements ZooComponent {
@Override
public Zoo inject(Zoo zoo) {
return injectZoo(zoo);
}
private Zoo injectZoo(Zoo instance) {
// providerTigerProvider.get():這裏是Tiger對象單例的關鍵所在
// Zoo_MembersInjector.injectTiger():真實的賦值動作在該方法中
Zoo_MembersInjector.injectTiger(instance, providerTigerProvider.get());
return instance;
}
}
providerTigerProvider.get()
上面分析過providerTigerProvider
是一個Provider
對象,它持有ZooModule_ProviderTigerFactory
對象,下面先看Provider.get()
public final class DoubleCheck<T> implements Provider<T>, Lazy<T> {
private DoubleCheck(Provider<T> provider) {
assert provider != null;
this.provider = provider; // 該變量爲ZooModule_ProviderTigerFactory對象.
}
@Override
public T get() {
Object result = instance;
if (result == UNINITIALIZED) {
synchronized (this) {
result = instance;
if (result == UNINITIALIZED) {
// 經過雙重判斷,如果result爲null,
// 那麼就調用ZooModule_ProviderTigerFactory.get()獲取tiger對象賦值給result變量
result = provider.get();
instance = reentrantCheck(instance, result);
provider = null;
}
}
}
// 最終將tiger對象返回
return (T) result;
}
}
ZooModule_ProviderTigerFactory.get()
public final class ZooModule_ProviderTigerFactory implements Factory<Tiger> {
@Override
public Tiger get() {
return providerTiger(module);
}
public static Tiger providerTiger(ZooModule instance) {
// ZooModule_ProviderTigerFactory.get()最終調用的方法是 ZooModule.providerTiger(),最終返回Module創建的tiger對象.
return Preconditions.checkNotNull(instance.providerTiger(), "Cannot return null from a non-@Nullable @Provides method");
}
}
Zoo_MembersInjector.injectTiger(instance, providerTigerProvider.get())
最終的賦值動作在該方法中
public final class Zoo_MembersInjector implements MembersInjector<Zoo> {
@InjectedFieldSignature("com.yey.dagger2.Zoo.tiger")
public static void injectTiger(Zoo instance, Object tiger) {
instance.tiger = (Tiger) tiger;
}
}
總結
- 當
Module
中增加了@Singleton
註解,那麼依賴該Module
的注射器也得增加@Singleton
註解,否則報錯. Module
中方法增加@Singleton
註解,當前方法返回的對象時,會對該返回的對象進行雙重檢查,保證該對象是單例.@Singleton
註解是與每個注射器的生命週期同步,兩個不同的注射器其實會創建兩個tiger
對象,但是在同一個注射器下,tiger
對象纔是單例.
注射器相互依賴時使用@Scope
class Tiger {
public void sleep() {
System.out.println("Tiger sleeping");
}
}
@Module
class ZooModule {
// 表示Tiger對象是單例.
@Singleton
@Provides
public Tiger providerTiger() {
return new Tiger();
}
}
// ZooComponent注射器使用了@Singleton,當另外一個注射器依賴它時,也需要添加一個@Scope類型註釋.
@Singleton
@Component(modules = {ZooModule.class})
interface ZooComponent {
Tiger provider();
}
// 假如PlaygroundComponent注射器依賴ZooComponent注射器,因爲ZooComponent有@Singleton註釋,
// 所以PlaygroundComponent注射器也必須增加一個Scope註釋,並且不允許和@Singleton註釋相同,
// 那麼只有自定義一個@MyScope註釋
@MyScope
@Component(dependencies = {ZooComponent.class})
interface PlaygroundComponent {
Playground inject(Playground playground);
}
//自定義一個MyScope註釋
@Scope
@Documented
@Retention(RUNTIME)
public @interface MyScope {}
其實@Singleton
註釋和@MyScope
功能是一樣的,只是名字不同而已,上面的代碼中將他們兩個調換完全可以.在同一個注射器的生命週期範圍裏,用@Singleton
標註的方法獲取到的對象是一個單例.