本教程主要详细讲解Guice依赖注入中的一些高级选项,他们分别是ScopeEagerly Loading BindingsStageOptional Injection。我们将一一对他们进行讲解。

基础环境


技术 版本
Java 1.8+
Guice 4.2.3

初始化项目


  • 初始化项目
mvn archetype:generate -DgroupId=com.edurt.sli.guice -DartifactId=guice-binder-scope -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false
  • 修改pom.xml增加Guice依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>spring-learn-integration</artifactId><groupId>com.edurt.sli</groupId><version>1.0.0</version></parent><modelVersion>4.0.0</modelVersion><artifactId>guice-binder-scope</artifactId><name>Guice依赖注入(Scope)</name><properties><system.java.version>1.8</system.java.version><guice.version>4.2.3</guice.version><lombok.version>1.18.2</lombok.version></properties><dependencies><dependency><groupId>com.google.inject</groupId><artifactId>guice</artifactId><version>${guice.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>${plugin.maven.compiler.version}</version><configuration><source>${system.java.version}</source><target>${system.java.version}</target></configuration></plugin></plugins></build></project>

guice: guice就是我们核心要使用的依赖

Singleton


Guice支持我们在其他DI框架中逐渐习惯的ScopeScope机制。Guice默认提供已定义依赖项的新实例。

  • 创建Service接口,用于提供使用的测试使用到的方法,代码如下
package com.edurt.sli.guice.scope;public interface Service
{void println(String source);
}
  • 创建ScopeService类,用于构建对Service的实现
package com.edurt.sli.guice.scope;import java.time.LocalDateTime;public class ScopeServiceimplements Service
{@Overridepublic void println(String source){System.out.println(String.format("%s on %s", source, LocalDateTime.now()));}
}
  • 创建用于测试注入的应用类ScopeApplication,代码如下
package com.edurt.sli.guice.scope;import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Scopes;public class ScopeApplication
{public static void main(String[] args){Injector injector = Guice.createInjector(binder -> binder.bind(Service.class).to(ScopeService.class).in(Scopes.SINGLETON));Service service = injector.getInstance(Service.class);service.println("Singleton Scope");}
}

我们运行程序输出

Scope on 2020-12-18T16:01:37.792656

通过代码binder.bind(Service.class).to(ScopeService.class).in(Scopes.SINGLETON)我们指定了ScopeService的Scope,他将会被标志为一个单例实例。当然我们也可以使用@Singleton标志该类的作用域,我们修改ScopeService类文件代码如下:

package com.edurt.sli.guice.scope;import javax.inject.Singleton;import java.time.LocalDateTime;@Singleton
public class ScopeServiceimplements Service
{@Overridepublic void println(String source){System.out.println(String.format("%s on %s", source, LocalDateTime.now()));}
}

ScopeApplication中的binder.bind(Service.class).to(ScopeService.class).in(Scopes.SINGLETON)代码修改为binder.bind(Service.class).to(ScopeService.class)

两种方式实现的效果都是一致的。此时ScopeService会被构建为单例实例。

当然还有一个asEagerSingleton()方法也可以用来标记单例模式。

他们的对比图如下:

使用方式 PRODUCTION DEVELOPMENT
.asEagerSingleton() eager eager
.in(Singleton.class) eager lazy
.in(Scopes.SINGLETON) eager lazy
@Singleton eager* lazy

自定义Scope


Guice还支持我们用户自定义作用域,通常情况下我们不需要自己实现Scope,一般内置的作用域对于大多数的应用已经足够了。如果您正在编写一个web应用程序,那么ServletModule为HTTP请求和HTTP会话提供了简单的、良好作用域实现是一个很好的想法。

  • 自定义Scope注解

Scope注解用于标记当前Scope在容器中使用的作用域。将使用它来注释guice构造的类型,@Provides方法和bind语法中的in()。Scope注解代码如下:

package com.edurt.sli.guice.seso;import com.google.inject.ScopeAnnotation;import java.lang.annotation.Retention;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;@Target({TYPE, METHOD})
@Retention(RUNTIME)
@ScopeAnnotation
public @interface CustomScope
{}

在使用自定义Scope时,请确保导入了正确的Scope注解。否则,您可能会得到一个SCOPE_NOT_FOUND错误。

  • 实现Scope接口

Scope接口确保每个Scope实例拥有一到多个类型实例。实现的Scope接口代码如下:

package com.edurt.sli.guice.seso;import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Scope;public class CustomScopeImplimplements Scope
{ThreadLocal<Object> threadLocal = new ThreadLocal<>();@Overridepublic <T> Provider<T> scope(Key<T> key, Provider<T> unscoped){return () -> {T instance = (T) threadLocal.get();if (instance == null) {instance = unscoped.get();threadLocal.set(instance);}return instance;};}
}

我们在上述代码中实现了一个简单线程抽取Scope,我们只是为了做测试使用,具体的Scope还需要根据业务自己使用。当我们传递的线程中没有构造一个对象时,先构造一个,然后放入线程上下文中,以后每次都从线程中获取对象。

  • 使用创建CustomScopeApplication用来使用自定义的Scope代码如下:
package com.edurt.sli.guice.seso;import com.google.inject.Guice;
import com.google.inject.Injector;public class CustomScopeApplication
{public static void main(String[] args){Injector injector = Guice.createInjector(binder -> {binder.bind(Service.class).to(ScopeService.class).in(new CustomScopeImpl());});for (int i = 0; i < 3; i++) {System.out.println(injector.getInstance(Service.class).hashCode());}}
}

运行程序后我们得到以下结果:

1574598287
1574598287
1574598287

我们通过结果得到运行了3次后的实例hashCode是一致的,这就说明我们的自定义Scope已经起作用了。如果新的实例构建后那么hashCode将会被改变。

  • 绑定自定义Scope注解,我们通过实现Module进行注入
package com.edurt.sli.guice.seso;import com.google.inject.AbstractModule;public class CustomScopeModuleextends AbstractModule
{@Overrideprotected void configure(){bindScope(CustomScope.class, new CustomScopeImpl());}
}

需要使用到改Module只需要在Guice.createInjector构建的时候添加该Module即可,代码如下:

Injector injector = Guice.createInjector(new CustomScopeModule(), binder -> {binder.bind(Service.class).to(ScopeService.class).in(new CustomScopeImpl());});

ScopeService类上使用@CustomScope注解即可。

打包文件部署


  • 打包数据
mvn clean package -Dmaven.test.skip=true -X

运行打包后的文件即可

java -jar target/guice-binder-scope-1.0.0.jar

源码地址


  • GitHub

Guice依赖注入(Scope)相关推荐

  1. guice依赖注入原理_Google Guice依赖注入示例教程

    guice依赖注入原理 Google Guice is the framework to automate the dependency injection in applications. If y ...

  2. 锡兰的Weld和Guice依赖注入

    我个人对依赖注入的好处持矛盾态度. 一方面,我认识到它在某些容器环境(例如Java EE)中的有用性. (根据记录,我是JCP专家组的CDI 1.0规范的作者.)另一方面,鉴于我过去几年一直在从事的工 ...

  3. Google Guice 一个轻量级的依赖注入框架

    1.美图 2.概述 2.1 背景 在做项目的时候,看见有段代码直接是使用Google Guice 注入了avaitor表达式. 2.1 官网 Github 主页:https://github.com/ ...

  4. Google开源依赖注入框架-Guice指南

    持续坚持原创输出,点击蓝字关注我吧 作者:软件质量保障 知乎:https://www.zhihu.com/people/iloverain1024 之前发过一篇文章<浅谈依赖注入的实现>, ...

  5. Android依赖注入:Google Guice on Android的使用及相关资源

    本文转自:http://blog.csdn.net/sangming/article/details/8878104 RoboGuice 使用谷歌自己的Guice库,给Android带来了简单和易用的 ...

  6. Guice:最好用的依赖注入框架

    首先在你的maven项目里引入 还可以自动注入Set,Map容器,但是得首先加上扩展库 我没有使用官方的例子,写个最简单的HelloWorld Guice里最常用的两个注解就是@Singleton和@ ...

  7. [Android]使用Dagger 2依赖注入 - 自定义Scope(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5095426.html 使用Dagger 2依赖注入 - 自定义 ...

  8. Java 依赖注入标准(JSR-330)简介

    Java 依赖注入标准(JSR-330)简介 转载请保留作者信息: 作者:88250 ,Vanessa 时间:2009 年 11 月 19 日 Java 依赖注入标准(JSR-330,Dependen ...

  9. 依赖注入Dagger2详解

    为什么使用依赖注入 首先我们需要知道,人们在很长的一段时间里都是利用控制反转原则规定:应用程序的流程取决于在程序运行时对象图的建立.通过抽象定义的对象交互可以实现这样的动态流程.而使用依赖注入技术或者 ...

  10. [Android]使用Dagger 2依赖注入 - DI介绍(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5092083.html 使用Dagger 2依赖注入 - DI介 ...

最新文章

  1. Bloglines手机伴侣支持走cmwap代理了
  2. cmake 静态编译 简介
  3. 数据库:MySQL相关知识整理,值得收藏!
  4. 分布式系统的开发经验与心得
  5. 洛谷 P3367 ---- 【模板】并查集
  6. Webydo:一款在线自由创建网站的 Web 应用
  7. matlab 均值滤波
  8. Protocol(一)[概述]
  9. 2021/10/04 git 详细流程
  10. 每一个都能笑抽的 39 个奇葩代码注释
  11. POSCMS 短信设置
  12. 初识C语言 二(数据类型、变量和常量)
  13. MySQL8 的安装
  14. 手机、电脑、服务器电子数据现场勘验攻略(超级全!)
  15. windows11编译OpenCV4.5.0 with CUDA(附注意事项)
  16. ORA-21561: OID generation failed
  17. 微信网页授权的制作步骤
  18. OpenStreetMap在线地图数据下载(全)
  19. 2023最新版视频打赏系统源码/很稳定运行+二开改进过的
  20. 腾讯股票接口API(3)——根据股票代码获取分时数据

热门文章

  1. 奔图打印机驱动linux安装方法,奔图3100打印机驱动
  2. 白光led 计算机模拟,白光LED在TracePro中的建模及仿真
  3. dt100g3什么意思_酷黑滑盖风 金士顿DT100G3优盘评测
  4. 交互式反汇编器 linux,Carbon:交互式反汇编工具
  5. Hive微博数据统计分析
  6. python新浪微博爬虫_利用新浪API实现数据的抓取\微博数据爬取\微博爬虫
  7. python爬微博数据中心,网易微博爬虫(自定义关键字爬取微博数据)(附软件源码)...
  8. iOS ApplePay paymentData 加解密 (待续)
  9. 金桔智能门锁实现人证房三统一原理
  10. AI 诊断新算法,可提前十年查出老年痴呆症;济南酒店推行“人脸识别”,没带证件也可住店...