@Module
@Module注解在類或接口上,表明該類或接口用于提供相關(guān)依賴。該類或接口中使用的注解有@Provides堡掏,@Binds,@IntoSet刨疼,@IntoMap泉唁。
@Provides
最常用,注解在非抽象方法上揩慕,返回值是程序中需要用到的依賴亭畜。
代碼:
@Module
public class ProvidesModule {
/* 形式一:自己構(gòu)建Windable實例
@Provides
public Windable provideWindable(){
return new WindableImpl();
}*/
/**
* 形式二:讓Dagger構(gòu)建Windable實例,此時需要在WindableImpl構(gòu)造函數(shù)上打上@Inject注解
*/
@Provides
public Windable provideWindable(WindableImpl windable){
return windable;
}
}
針對@Provides注解迎卤,編譯期Dagger會生成格式為:
Module類名_方法名Factory 的類并且實現(xiàn)了Factory接口拴鸵。
針對本例生成的類就是ProvidesModule_ProvideWindableFactory
public final class ProvidesModule_ProvideWindableFactory implements Factory<Windable> {
private final ProvidesModule module;
private final Provider<WindableImpl> windableProvider;
public ProvidesModule_ProvideWindableFactory(
ProvidesModule module, Provider<WindableImpl> windableProvider) {
this.module = module;
this.windableProvider = windableProvider;
}
@Override
public Windable get() {
return provideInstance(module, windableProvider);
}
public static Windable provideInstance(
ProvidesModule module, Provider<WindableImpl> windableProvider) {
return proxyProvideWindable(module, windableProvider.get());
}
public static ProvidesModule_ProvideWindableFactory create(
ProvidesModule module, Provider<WindableImpl> windableProvider) {
return new ProvidesModule_ProvideWindableFactory(module, windableProvider);
}
public static Windable proxyProvideWindable(ProvidesModule instance, WindableImpl windable) {
return Preconditions.checkNotNull(
instance.provideWindable(windable),
"Cannot return null from a non-@Nullable @Provides method");
}
}
生成的類的格式也是相對固定的。
一個靜態(tài)create方法蜗搔,返回值是該Factory類實例劲藐。
一個構(gòu)造函數(shù)。
一個get方法樟凄,來自Factory接口聘芜,用于返回依賴。
注意:每個用@Provides注解的方法都會生成相應(yīng)的Factory類缝龄。
@Binds
也是用于提供依賴汰现,跟@Provides注解功能一樣。不同的是@Binds注解于抽象方法上叔壤,返回值是依賴的接口或父類型或本類型瞎饲,方法只有一個參數(shù),就是返回值的實現(xiàn)者炼绘。既然@Binds注解于抽象方法嗅战,那么@Module注解的類就必須是接口或抽象類了。
代碼:
@Module
public interface BindsModule {
/**
* 注解于抽象方法俺亮,只能有一個參數(shù)
* @param windable
* @return
*/
@Binds
Windable provideWindable(WindableImpl windable);
}
@IntoSet
@IntoSet需要聯(lián)合@Provides一起使用仗哨,@IntoSet注解的方法表示方法返回值放入一個Set集合中,多個@IntoSet注解的方法铅辞,若方法返回值類型一致厌漂,則會放入同一個Set集合中。
@Module
public class IntoSetModule {
@Provides
@IntoSet
public String provideA(){
return "A";
}
@Provides
@IntoSet
public String provideB(){
return "B";
}
}
public class IntoSetDemo {
@Inject
Set<String> letters;
IntoSetDemo(){
}
public static void main(String[] args){
IntoSetDemo demo=new IntoSetDemo();
DaggerIntoSetComponent.create().inject(demo);
for (String letter:demo.letters){
System.out.print(letter);
}
}
}
Module類中的provideA和provideB方法的返回值被放入同一個Set集合中斟珊,所以該例的輸出結(jié)果是AB苇倡。
@IntoMap
@IntoMap需要聯(lián)合@IntKey,@StringKey或者自定義的@MapKey以及@Provides一起使用富纸。如果map的key為int類型,則用@IntKey,為String類型旨椒,則用@StringKey晓褪,如果為其他類型,則需要自定義注解综慎,并在自定義注解上打上@MapKey涣仿。
@Module
public class IntoMapModule {
@Provides
@IntoMap
@IntKey(1)
public String provideNameA(){
return "nameA";
}
@Provides
@IntoMap
@IntKey(2)
public String provideNameB(){
return "nameB";
}
}
public class IntoMapDemo {
@Inject
Map<Integer,String> map;
IntoMapDemo(){
}
public static void main(String[] args){
IntoMapDemo demo=new IntoMapDemo();
DaggerIntoMapComponent.create().inject(demo);
System.out.println("key=1,value="+demo.map.get(1));
System.out.println("key=2,value="+demo.map.get(2));
}
}
IntoMapModule類中的provideNameA方法指定了key為1,value為nameA示惊,provideNameB方法指定了key為2好港,value為nameB,他們被放入同一個map中米罚。所以程序的輸出結(jié)果是
key=1,value=nameA
key=2,value=nameB
@Component
@Component 注解的類(一般是接口或抽象類)用于為具體的類注入依賴钧汹。
@Component 注解有兩個屬性:
一個是modules屬性,關(guān)聯(lián)相關(guān)的Module
一個是dependencies屬性录择,關(guān)聯(lián)子Component
一般需要提供一個inject()方法拔莱,參數(shù)是需要注入的類;當然也可以定義一個直接獲取依賴的方法隘竭,比如Activity類中需要注入一個Presenter對象塘秦,可以直接在Component接口中定義一個presenter方法,在Activity類中需要使用Presenter時使用component.presenter()就可以了动看。
a.inject法:
@Component(modules = MyModule.class)
public interface MyComponent {
/**
* 定義一個inject方法尊剔,注入ComponentDemo需要的依賴
* @param componentDemo
*/
void inject(ComponentDemo componentDemo);
}
public class ComponentDemo {
@Inject
MyService myService;
ComponentDemo(){
}
public static void main(String args[]){
ComponentDemo componentDemo=new ComponentDemo();
//將MyService注入
DaggerMyComponent.create().inject(componentDemo);
componentDemo.myService.serve();
}
}
MyModule提供了MyService實例。
b.Component提供一個myService()方法
@Component(modules = MyModule.class)
public interface MyComponent {
//定義一個方法提供依賴
MyService myService();
}
public class ComponentDemo {
MyService myService;
ComponentDemo(){
}
public static void main(String args[]){
ComponentDemo componentDemo=new ComponentDemo();
componentDemo.myService=DaggerMyComponent
.create()
.myService();
componentDemo.myService.serve();
}
}
@Component注解在編譯期生成的源碼格式:
1弧圆,實現(xiàn)@Component注解的接口
2赋兵,靜態(tài)內(nèi)部類Builder笔咽,含有用于設(shè)置@Component注解中modules的方法
3搔预,生成的Component類名為@Component注解的接口的簡單名稱加前綴Dagger。
4叶组,一個接收builder的構(gòu)造函數(shù)拯田,保存相關(guān)的module。
5甩十,實現(xiàn)@Component注解的接口中定義的方法
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class DaggerMyComponent implements MyComponent {
private MyModule myModule;
private DaggerMyComponent(Builder builder) {
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static MyComponent create() {
return new Builder().build();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.myModule = builder.myModule;
}
@Override
public MyService myService() {
return MyModule_ProvideMyServiceFactory.proxyProvideMyService(myModule);
}
public static final class Builder {
private MyModule myModule;
private Builder() {}
public MyComponent build() {
if (myModule == null) {
this.myModule = new MyModule();
}
return new DaggerMyComponent(this);
}
public Builder myModule(MyModule myModule) {
this.myModule = Preconditions.checkNotNull(myModule);
return this;
}
}
}
@Inject
當@Inject標注在構(gòu)造器時船庇,說明該類的實例交由Dagger生成,Dagger會在編譯期間生成一個XXX_Factory類侣监。
當@Inject標注在字段上時鸭轮,Dagger會在編譯期生成一個XXX_MembersInjector類。
public class MapKeyDemo {
@Inject
Map<Bar,Integer> map;
private String param;
@Inject
public MapKeyDemo(String param){
this.param=param;
}
public static void main(String [] args){
MapKeyComponent mapKeyComponent=DaggerMapKeyComponent.create();
MapKeyDemo mapKeyDemo=mapKeyComponent.mapKeyDemo();
mapKeyComponent.inject(mapKeyDemo);
}
}
生成的類
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class MapKeyDemo_Factory implements Factory<MapKeyDemo> {
private final Provider<String> paramProvider;
private final Provider<Map<Bar, Integer>> mapProvider;
public MapKeyDemo_Factory(
Provider<String> paramProvider, Provider<Map<Bar, Integer>> mapProvider) {
this.paramProvider = paramProvider;
this.mapProvider = mapProvider;
}
@Override
public MapKeyDemo get() {
return provideInstance(paramProvider, mapProvider);
}
public static MapKeyDemo provideInstance(
Provider<String> paramProvider, Provider<Map<Bar, Integer>> mapProvider) {
MapKeyDemo instance = new MapKeyDemo(paramProvider.get());
MapKeyDemo_MembersInjector.injectMap(instance, mapProvider.get());
return instance;
}
public static MapKeyDemo_Factory create(
Provider<String> paramProvider, Provider<Map<Bar, Integer>> mapProvider) {
return new MapKeyDemo_Factory(paramProvider, mapProvider);
}
public static MapKeyDemo newMapKeyDemo(String param) {
return new MapKeyDemo(param);
}
}
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class MapKeyDemo_MembersInjector implements MembersInjector<MapKeyDemo> {
private final Provider<Map<Bar, Integer>> mapProvider;
public MapKeyDemo_MembersInjector(Provider<Map<Bar, Integer>> mapProvider) {
this.mapProvider = mapProvider;
}
public static MembersInjector<MapKeyDemo> create(Provider<Map<Bar, Integer>> mapProvider) {
return new MapKeyDemo_MembersInjector(mapProvider);
}
@Override
public void injectMembers(MapKeyDemo instance) {
injectMap(instance, mapProvider.get());
}
public static void injectMap(MapKeyDemo instance, Map<Bar, Integer> map) {
instance.map = map;
}
}
@Subcomponent
Subcomponent可以使用Component提供的依賴橄霉,因此一些公共的組件信息可以由Component提供窃爷。
Component和Module
@Module
public class MyModule {
@Provides
public MyService provideMyService(){
return new MyService();
}
}
@Component(modules = MyModule.class)
public interface MyComponent {
//添加Subcomponent
MySubComponent plus(MySubModule mySubModule);
}
Subcomponent和它的Module
@Module
public class MySubModule {
}
@Subcomponent(modules = MySubModule.class)
public interface MySubComponent {
void inject(SubcomponentDemo demo);
}
注意MyService是在MyModule中提供的而不是MySubModule提供的
使用
public class SubcomponentDemo {
@Inject
MyService myService;
SubcomponentDemo() {
}
public static void main(String[] args) {
SubcomponentDemo demo = new SubcomponentDemo();
DaggerMyComponent
.builder()
.build()
.plus(new MySubModule())//向Component中添加SubComponent,并返回SubComponent
.inject(demo);//注入依賴
demo.myService.serve();//成功注入,說明subcomponent可以使用component提供依賴
}
}
看一下生成的Component源碼
public final class DaggerMyComponent implements MyComponent {
private MyModule myModule;
private DaggerMyComponent(Builder builder) {
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static MyComponent create() {
return new Builder().build();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.myModule = builder.myModule;
}
@Override
public MySubComponent plus(MySubModule mySubModule) {
return new MySubComponentImpl(mySubModule);
}
public static final class Builder {
private MyModule myModule;
private Builder() {}
public MyComponent build() {
if (myModule == null) {
this.myModule = new MyModule();
}
return new DaggerMyComponent(this);
}
public Builder myModule(MyModule myModule) {
this.myModule = Preconditions.checkNotNull(myModule);
return this;
}
}
/**
* Subcomponent以內(nèi)部類形式存在于Component類中
*/
private final class MySubComponentImpl implements MySubComponent {
private MySubComponentImpl(MySubModule mySubModule) {}
@Override
public void inject(SubcomponentDemo demo) {
injectSubcomponentDemo(demo);
}
@CanIgnoreReturnValue
private SubcomponentDemo injectSubcomponentDemo(SubcomponentDemo instance) {
SubcomponentDemo_MembersInjector.injectMyService(
instance,
MyModule_ProvideMyServiceFactory.proxyProvideMyService(DaggerMyComponent.this.myModule));
return instance;
}
}
}
可以看到 Subcomponent以內(nèi)部類形式存在于Component類中