目录
依赖注入概念
Guice框架的简单使用
依赖注入概念
依赖
在讲解依赖注入概念之前,我们可以先了解下依赖的概念,依赖就是当ClassA需要调用ClassB的任意方法时候,我们可以认为ClassA是ClassB的依赖,反之也可以理解为ClassA依赖于ClassB。
public class ClassA {
ClassB classB = new ClassB();
double taxes(){
return classB.salary() * 0.45d;
}
}
class ClassB {
int salary() {
return 999999;
}
}
在这个例子中,ClassA通过调用ClassB返回的年收入来进行计算税费。
上面的方式会增加调用者与被调用者之间的耦合,不利于后期的升级与维护。
依赖注入(Dependency Injection)
依赖注入是一种用来实现控制反转的软件设计模式,依赖注入将调用者和被调用者分离开来,调用者不再实例化被调用者,从而达到解耦的目的。
依赖注入有三种类型的类:
1.客户类:客户类依赖于服务类,相当于例子中的ClassA
2.服务类:服务类提供服务给客户类,相当于例子中的ClassB
3.Injector 类:Injector会实例化服务类,将服务类注入给客户类进行使用
Guice框架的简单使用
环境配置
Gradle
implementation 'com.google.inject:guice:5.1.0'
Maven
com.google.inject guice5.1.0
步骤1:创建Interface
public interface SpellChecker {
void checkSpelling();
}
步骤2:实现Interface
public class SpellCheckerImpl implements SpellChecker{
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
步骤3:创建Binds Module
import com.google.inject.AbstractModule;
public class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
//将Interface绑定到具体的实现类
bind(SpellChecker.class).to(SpellCheckerImpl.class);
}
}
步骤4:使用inject
import com.google.inject.Inject;
public class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor(SpellChecker spellChecker){
this.spellChecker = spellChecker;
}
public void makeSpellCheck() {
//可以直接通过interface调用方法
spellChecker.checkSpelling();
}
}
步骤5:具体使用
import com.google.inject.Guice;
import com.google.inject.Injector;
public class GuiceTest {
public static void main(String[] args){
//创建injector
Injector injector = Guice.createInjector(new TextEditorModule());
//从injector中获取TextEditor对象
TextEditor editor = injector.getInstance(TextEditor.class);
//调用实例方法
editor.makeSpellCheck();
}
}
上面的例子是构造方法注入,一般都是用这种方式比较多。
@Provides的使用
将需要注入的方法编写在Module中,并且在方法上加@Provides注解
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
public class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
}
@Provides
public String stringProvides(){
return "test".toUpperCase();
}
}
import com.google.inject.Inject;
public class TextEditor {
private String string;
//将stringProvides方法注入
@Inject
public TextEditor(String string){
this.string = string;
}
public void makeSpellCheck() {
System.out.println(string);
}
}
import com.google.inject.Guice;
import com.google.inject.Injector;
public class GuiceTest {
public static void main(String[] args){
//创建injector
Injector injector = Guice.createInjector(new TextEditorModule());
//从injector中获取TextEditor对象
TextEditor editor = injector.getInstance(TextEditor.class);
//调用实例方法
editor.makeSpellCheck();
}
}
Provider Interface的使用
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
TextEditor editor = injector.getInstance(TextEditor.class);
editor.makeSpellCheck();
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public TextEditor( SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class)
.toProvider(SpellCheckerProvider.class);
}
}
//spell checker interface
interface SpellChecker {
public void checkSpelling();
}
//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
private String dbUrl;
private String user;
private Integer timeout;
@Inject
public SpellCheckerImpl(String dbUrl,
String user,
Integer timeout){
this.dbUrl = dbUrl;
this.user = user;
this.timeout = timeout;
}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
System.out.println(dbUrl);
System.out.println(user);
System.out.println(timeout);
}
}
class SpellCheckerProvider implements Provider{
@Override
public SpellChecker get() {
String dbUrl = "jdbc:mysql://localhost:5326/emp";
String user = "user";
int timeout = 100;
SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
return SpellChecker;
}
}
@Singleton单例模式
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
public class GuiceTester {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TextEditorModule());
SpellChecker spellChecker = new SpellCheckerImpl();
injector.injectMembers(spellChecker);
TextEditor editor = injector.getInstance(TextEditor.class);
System.out.println(editor.getSpellCheckerId());
TextEditor editor1 = injector.getInstance(TextEditor.class);
System.out.println(editor1.getSpellCheckerId());
}
}
class TextEditor {
private SpellChecker spellChecker;
@Inject
public void setSpellChecker(SpellChecker spellChecker){
this.spellChecker = spellChecker;
}
public TextEditor() { }
public void makeSpellCheck(){
spellChecker.checkSpelling();
}
public double getSpellCheckerId(){
return spellChecker.getId();
}
}
//Binding Module
class TextEditorModule extends AbstractModule {
@Override
protected void configure() {
bind(SpellChecker.class).to(SpellCheckerImpl.class);
}
}
interface SpellChecker {
public double getId();
public void checkSpelling();
}
@Singleton
class SpellCheckerImpl implements SpellChecker {
double id;
public SpellCheckerImpl(){
id = Math.random();
}
@Override
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
@Override
public double getId() {
return id;
}
}
参考资源:
Google Guice Tutorial (tutorialspoint.com)
github.com



