dagger2
2015-11-18 13:49:32 0 举报
AI智能生成
Dagger2
作者其他创作
大纲/内容
依赖注入
控制反转原则
应用流程取决于运行时构建的对象图
通过抽象定义出对象交互使动态流成为可能
运行时绑定的途径有依赖注入或服务加载
依赖注入的诱惑
外部配置和注入,组件可重用
协作是定义在抽象层面的,修改对象的实现并不需要改基本代码.在一个地方实例化就可以隔离和解耦
依赖可以注入到组件,好测试(注入mock对象)
对象和协作者无需知晓创建及生命周期(依赖注入框架接管)
JSR-330
Java依赖注入
一套类注入的注释标准
重用性最大化
可测性最大化
维护性最大化
实现
Dagger2
Dagger1
Guice
Dagger1
原理
多点注入:依赖注入
多次绑定:提供依赖
多模块:一个功能由一套绑定实现
多个对象图:用一套模块实现一个范围
特点
编译时绑定
用反射来构建依赖图(不用在对象实例化)
运行时处理
问题
效率损耗
调试难
Dagger2
简介
Google在Dagger1上引出
加入google的AutoValue项目
最初想借代码生成来解决问题
进步与代价
无反射:编译时验证,配置和预处理
好调试跟踪:完整具体的调用栈
高效:google自称13%的效率提升
代码安全:方法派遣,高仿手写代码
灵活性降低:不用反射,缺少动态机制
依赖注入
概念
@Inject, 请求依赖, Dagger据此构造被注解的类和成员实例,已满足依赖
@Module,提供依赖的类,可分解,可组合,Dagger在此找依赖
@Provide,在module里的方法前,Dagger据此知道想构造和提供的依赖项
@Component,桥接@Inject和@Module
@Scope,自定义Scope可以定义注入对象的粒度,如@PerActivity, @PerFragment, @PerUser
@Qualifier, 补充说明类的类型,如对Context可用@ForApplication, @ForActivity
代码
build.gradle
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'
compile 'com.google.dagger:dagger:2.0'
...
}
编译器, 运行库, apt插件
初始化对象
@Override void initializePresenter() {
// All this dependency initialization could have been avoided by using a
// dependency injection framework. But in this case this is used this way for
// LEARNING EXAMPLE PURPOSE.
ThreadExecutor threadExecutor = JobExecutor.getInstance();
PostExecutionThread postExecutionThread = UIThread.getInstance();
JsonSerializer userCacheSerializer = new JsonSerializer();
UserCache userCache = UserCacheImpl.getInstance(getActivity(), userCacheSerializer,
FileManager.getInstance(), threadExecutor);
UserDataStoreFactory userDataStoreFactory =
new UserDataStoreFactory(this.getContext(), userCache);
UserEntityDataMapper userEntityDataMapper = new UserEntityDataMapper();
UserRepository userRepository = UserDataRepository.getInstance(userDataStoreFactory,
userEntityDataMapper);
GetUserDetailsUseCase getUserDetailsUseCase = new GetUserDetailsUseCaseImpl(userRepository,
threadExecutor, postExecutionThread);
UserModelDataMapper userModelDataMapper = new UserModelDataMapper();
this.userDetailsPresenter =
new UserDetailsPresenter(this, getUserDetailsUseCase, userModelDataMapper);
}
本类需要知道太多对象创建和提供依赖的边角代码
依赖注入的方案
依赖图:Application Component
Application Module @Provide @Singleton
Activity Component
Activity Module @Provide @PerActivity
User Component
User Module @Provide @PerActivity
详解
Application Component,全应用生命周期的component,注入AndroidApplication和BseActivity类
@Singleton // Constraints this component to one-per-application or unscoped bindings.
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
void inject(BaseActivity baseActivity);
//Exposed to sub-graphs.
Context context();
ThreadExecutor threadExecutor();
PostExecutionThread postExecutionThread();
UserRepository userRepository();
}
@Singleton,应用内唯一component
module中的类必须明确向外暴露,否则不可见
Application Module, 提供全应用周期的对象
@Module
public class ApplicationModule {
private final AndroidApplication application;
public ApplicationModule(AndroidApplication application) {
this.application = application;
}
@Provides @Singleton Context provideApplicationContext() {
return this.application;
}
@Provides @Singleton Navigator provideNavigator() {
return new Navigator();
}
@Provides @Singleton ThreadExecutor provideThreadExecutor(JobExecutor jobExecutor) {
return jobExecutor;
}
@Provides @Singleton PostExecutionThread providePostExecutionThread(UIThread uiThread) {
return uiThread;
}
@Provides @Singleton UserCache provideUserCache(UserCacheImpl userCache) {
return userCache;
}
@Provides @Singleton UserRepository provideUserRepository(UserDataRepository userDataRepository) {
return userDataRepository;
}
}
注入应用内全局对象, @Provide都带上@Singleton
Activity Component,Activity生命周期component
@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class)
public interface ActivityComponent {
//Exposed to sub-graphs.
Activity activity();
}
@PerActivity自定义,activity周期
@Scope
@Retention(RUNTIME)
public @interface PerActivity {}
能activity对象构建是注入
可在Activity范围内使用singleton模式
这些对象只在Activity里用,全局对象图保持清晰
Activity Module: 暴露activity给依赖图
@Module
public class ActivityModule {
private final Activity activity;
public ActivityModule(Activity activity) {
this.activity = activity;
}
@Provides @PerActivity Activity activity() {
return this.activity;
}
}
使用activity作为context的fragment
User Component: 扩展自AcitvityComponent
@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = {ActivityModule.class, UserModule.class})
public interface UserComponent extends ActivityComponent {
void inject(UserListFragment userListFragment);
void inject(UserDetailsFragment userDetailsFragment);
}
@PerActivity,activity生命周期,注入用户相关fragments
ActivityModule已经暴露activity context, 子modules不再做
User Module:用户相关的协作对象
@Module
public class UserModule {
@Provides @PerActivity GetUserListUseCase provideGetUserListUseCase(GetUserListUseCaseImpl getUserListUseCase) {
return getUserListUseCase;
}
@Provides @PerActivity GetUserDetailsUseCase provideGetUserDetailsUseCase(GetUserDetailsUseCaseImpl getUserDetailsUseCase) {
return getUserDetailsUseCase;
}
}
user的use cases, 取列表,取详情
注入依赖及绑定依赖顺序
构造函数注入:类的构造函数前加@Inject
成员对象注入:非私有成员对象前加@Inject
方法注入:方法前加@Inject
实例
BaseActivity:Navigator
public abstract class BaseActivity extends Activity {
@Inject Navigator navigator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getApplicationComponent().inject(this);
}
protected ApplicationComponent getApplicationComponent() {
return ((AndroidApplication)getApplication()).getApplicationComponent();
}
protected ActivityModule getActivityModule() {
return new ActivityModule(this);
}
}
成员注入,ApplicationModule显式提供依赖项
onCreate里调用getApplicationComponent()后inject注入
Application对象初始化ApplicationComponent
Activity-Fragment
activity范围UserComponent注入UserDetailsFragment,存在UserDetilsActivity里
private UserComponent userComponent;
private void initializeInjector() {
this.userComponent = DaggerUserComponent.builder()
.applicationComponent(getApplicationComponent())
.activityModule(getActivityModule())
.build();
}
Dagger实现component并以Dagger作为命名前缀,组合的component所以传入所有依赖的component和module参数
@Override public UserComponent getComponent() {
return userComponent;
}
为满足Fragment的依赖,提供接口
@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
this.getComponent.inject(this);
}
Fragment里调用Component的inject传入fragment参数
HasComponent接口类
public interface HasComponent {
C getComponent();
}
BaseFragment类
@SuppressWarnings("unchecked")
protected C getComponent(Class componentType) {
return componentType.cast(((HasComponent)getActivity()).getComponent());
}
Dagger2生成代码
DaggerApplicationComponent实现ApplicationComponent
0 条评论
下一页