依赖注入,ORM及相关框架

 
 
  • 基本概念
控制反转(Inversion of Control,英文缩写为IoC):创建被调用者的工作不再由调用者来完成,因此称为控制反转。
依赖注入(Dependency Injection,简称DI):控制反转的主要实现方式,可以通过反射方式实现(ViewUtils,反射注入),也可以非反射方式(Dagger2)
ORM:即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的sql语句打交道,只需简单的操作对象的属性方法。(Ormlite,dbutils,greendao)
 
 
  • Dagger2:

1.介绍:
依赖注入就是将调用者需要的另一个对象实例不在调用者内部实现,而是通过一定的方式从外部传入实例,解决了各个类之间的耦合。

那么这个外部,到底指的是哪里,如果指的是另一个类,那么,另一个类内部不就耦合了。能不能有一种方式,将这些构造的对象放到一个容器中,具体需要哪个实例时,就从这个容器中取就行了。那么,类的实例和使用就不在有联系了,而是通过一个容器将他们联系起来。实现了解耦。这个容器,便是。

是Google出的依赖注入框架。肯定有小伙伴疑问,为什么会有个 2 呢。该框架是基于开发的基础上开发的。

的原理是在编译期生成相应的依赖注入代码。这也是和其他依赖注入框架不同的地方,其他框架是在运行时期反射获取注解内容,影响了运行效率。

2.导入Dagger2:

在工程的文件添加插件:

dependencies {
classpath
'com.android.tools.build:gradle:2.1.2'

// 添加android-apt 插件
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}


app的build.gradle:

applyplugin:'com.android.application'

// 应用插件
apply plugin: 'com.neenbedankt.android-apt'


android {
compileSdkVersion
23
buildToolsversion"24.0.1"
defaultConfig {
applicationId"com.qf.zhouyi.daggertest"
minSdkVersion15
targetSdkVersionversionCode1
versionName"1.0"
}
buildTypes {
release {
minifyEnabledfalse
proguardFilesgetDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
}
}

lintOptions {
warning 'InvalidPackage'
}

}

dependencies {
compile filetree(
dir:'libs',89); background-color:inherit">include: ['*.jar'])
testCompile
'junit:junit:4.12'
compile'com.android.support:appcompat-v7:23.4.0'
// dagger 2 的配置
compile 'com.google.dagger:dagger:2.4'
apt 'com.google.dagger:dagger-compiler:2.4'
compile 'org.glassfish:javax.annotation:10.0-b28'

// 添加java 注解库
compile'com.google.code.gson:gson:2.7'
}

是编译器的插件,根据其官方文档,主要两个目的:

  • 编译时使用该工具,最终打包时不会将该插件打入到apk中。

  • 能够根据设置的源路径,在编译时期生成相应代码

    是主要的工具类库。为编译时期生成代码等相关的类库。

    在的文档中,也推荐使用这种方式。因为,编译时期生成代码的类库在运行期并不需要,那么将其分为两个库,(运行类库)和(编译器生成代码类库()),那么在打包时,就不需要将打入其中(用不到),减小APK 的大小。

3.使用

将程序分为三个部分。
- 实例化部分:对象的实例化。类似于容器,将类的实例放在容器里。
- 调用者:需要实例化对象的类。
- 沟通桥梁:利用中的一些API 将两者联系。

实例化部分:Module

package com.qf.zhouyi.daggerdemo;

import android.util.Logpublic class Person {


public void doSomething(){
Log.e("qf",89); background-color:inherit">"do something") }
}
packagecom.qf.zhouyi.daggerdemoimportdagger.Moduledagger.Provides
/**
* Created by zhouyi on 16/8/22.
*/
@Module
public classPersonModule {
@Provides
PersonprovidePerson(){
return newPerson()}
}

沟通部分

dagger.Component@Component(modules= {PersonModule.class})
public interfacePersonComponent {
voidinject(MainActivity mainActivity);
}

一个Component可以沟通多个module:

import  * Created by zhouyi on 16/8/22.
*/
modules = {PersonModule.class,GsonModule.public interface PersonComponent {
void ;
}
import com.google.gson.Gsonpublic class GsonModule {

Gson provideGosn(){
return new Gson() }
}
import android.os.Bundleimport android.support.v7.app.AppCompatActivityjavax.inject.Injectpublic class MainActivity extends AppCompatActivity {

@Inject
Person person Gson gson@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) DaggerPersonComponent.builder().build().inject(this) person.doSomething() String strjson = "{\n" +
" NAME:\"Albert Attard," P_LANGUAGE:Java" LOCATION:Malta\"\n"}" MyData myData = gson.fromJson(strjsonclass) Log.d( }
}


@Singleton 单例注解

假如,对于同一个对象,我们需要注入两次,如下方式:

person2        //person.doSomething();

Log.i("dagger""person = "+ person.toString()+"; person2 = "+ person2.toString());
}
}

打印出来的对象地址是不一样的

如果要使用单例,需要在module和component里加入singleton注解

class})
@Singleton
;
}
javax.inject.Singletonpublic class PersonModule {
@Singleton
Person providePerson(){
return new Person()但是,如果是不同的component,就无法保持单例:

import android.content.Intentimport android.view.View
}

onShow(View view) {
Intent intent = new Intent() intent.setClass(this,MainActivity2. startActivity(intent)android.support.annotation.Nullable */
public class MainActivity2 extends AppCompatActivity {
person3onCreate(@Nullable Bundle savedInstanceState) {
activity_main2)"person3 = "+ person3.toString()) void inject(MainActivity2 mainActivity2);
}

思考:如何得到全局的单例

带参数实例化

public class Person {

int aa public Person(int a){
aa = a }


"do something " + aa) }
}
public class PersonModule {
PersonModule( }

return new Person( }

}

调用


DaggerPersonComponent
.builder()
.personModule(new PersonModule(4))
.build()
.inject(;
;

一个创建依赖另一个创建:

public class IntModule {
int providesInt(){
return 5modules = IntModule.class)
public interface IntComponent {
provideInt()public class PersonModule {
// int aa;
//
// PersonModule(int a){
// aa = a;
// }
providePerson(int a){
return new Person(a) }

}
class}dependencies = IntComponent.class)
inject(MainActivity mainActivity)IntComponent intComponent = DaggerIntComponent.builder().build()
DaggerPersonComponent.builder()
.intComponent(intComponent)
.personModule(new PersonModule())
.build().inject(

多个不同的构造方法

    String mstrMsg    }

public Person(String strMsg){
mstrMsg = strMsgdoSomething2(){
Log.e("do something2"+mstrMsg) }
}

在上例的基础上,增加stringmodule,stringcomponent:

modules = StringModule.public interface StringComponent {
String provideString()public class StringModule {
String providesstring(){
return "abc"personcomponet:

dependencies = {IntComponent.PersonComponent {
//void inject(MainActivity2 mainActivity2);
}

personmodule:

javax.inject.Named//    String mstrMsg;
// PersonModule(String strMsg){
// mstrMsg = strMsg;
@Named("int")
int a){
return new Person(a)"string")
providePerson2(String strMsg){
return new Person(strMsg);
StringComponent stringComponent = DaggerStringComponent.builder().build()
DaggerPersonComponent.builder()
.intComponent(intComponent)
.stringComponent(stringComponent)
.personModule(person2.doSomething2()可以使用两个自定义注解替换前面的name注解:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface PersonInt {
}
PersonString {
}

懒加载Lazy和强制重新加载Provider

@PersonInt
@Inject
Lazy<Person> ;

Person p = person.get();
Log.i("person = "+ p.toString());
Person p2 = "person2 = "+ p2.toString());

上面打印出来地址一样

改成:

@Inject
Provider<Person> 打印地址不一样


package com.qf.zhouyi.ormlitetest ;

import android.os.Bundle ;
android.support.v7.app.AppCompatActivity android.util.Log java.util.List publicclass MainActivity extends AppCompatActivity{

@Override
protectedvoid onCreate (BundlesavedInstanceState){
super .onCreate(savedInstanceState) setContentView(R.layout. activity_main ) testAddUser() }

publicvoid testList ()
{
DatabaseHelperhelper=DatabaseHelper. getHelper ( this try
Useru1= new User( "zhy-android" , "2B青年" u1.setId( 2 List<User>users=helper.getUserDao().queryForAll() Log. e ( "TAG" users.toString()) } catch (Exceptione)
testAddUser {

"zhy" helper.getUserDao().create(u1) u1= "zhy2" "zhy3" "zhy4" "zhy5" "zhy6" testList() }

import com.j256.ormlite.field.DatabaseField com.j256.ormlite.table.DatabaseTable
@DatabaseTable ( tableName = "tb_user" )
User
@DatabaseField generatedId = true )
privateint id columnName "name" private String name "desc" desc public User()
User(Stringname Stringdesc)
. name =name desc =desc publicint getId return setId int id)
id =id String getName setName (Stringname)
getDesc setDesc (Stringdesc)
toString (){
return "User{" +
"id=" + ",name='" + ' \' ' '}' }
Dagger2Dagger2squaredaggerDagger2build.gradleandroid-aptandroid-aptGradledaggerdagger-compilerandroid-aptdaggerdagger-compilerdagger-compilerDagger2Dagger2Component

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...