3分钟带你了解:轻量级依赖注入框架Google Guice【享学Java】(下)

简介: 3分钟带你了解:轻量级依赖注入框架Google Guice【享学Java】(下)

注入


常用的注入方式有多种。


  • 简单的单一注入(接口的实现仅有一个类型)
如示例代码


  • Provider注入(具有延迟效果)
@Inject
private Provider<Animal> animal;


对于Provider方式,配置的方式也可这样来提供(类似于@Bean):


/

// 方法上是可以有入参的。但入参请确保已经是容器内的对象
@Provides // 作用类似于@Bean
@Singleton // 若这里不使用该注解,那就是多例,每次都会执行此方法
private Animal getAnimal(){
    return new Dog();
}


需要注意的是,若使用了@Provides方式配置了实例,那么向bind(Animal.class).toInstance(new Dog())这句话就不能再要了,否则就是重复绑定,启动时会抛错:



A binding to com.yourbatman.eurekaclient.guice.Animal was already configured at com.yourbatman.eurekaclient.guice.MainModule.configure(MainModule.java:11).
  at com.yourbatman.eurekaclient.guice.MainModule.getAnimal(MainModule.java:7)
  ...


  • 命名注入:用于对同一接口多个实现类做区分注入


bind(Animal.class).annotatedWith(DogAnno.class).to(Dog.class);
bind(Animal.class).annotatedWith(CatAnno.class).to(Cat.class);
@Inject
@DogAnno
private Animal animal;


除了自定义注解,你还可以使用Guice自带的命令类:Names.named("dog")(它返丝线了注解接口,所以返回值是个注解类型)。


Module之间的关系

创建一个Injector可以使用多个任意多个Module,因此需要明确它们的关系。


  • 并列:默认顺序传递就是此关系


Guice.createInjector(new MainModule(), .......);
  • 嵌套:大的Module可以嵌套任意多个子Module
public class ServerModule extends AbstractModule {
    @Override
    protected void configure() {
        install(new MainModule());
    }
}


  • 覆盖:如果有冲突的话后者覆盖前者,没有的话就都生效


// 用后者覆盖前者
Module finalModule = Modules.override(new MainModule()).with(new ServerModule());


@ImplementedBy 与 @ProvidedBy


单独介绍这两个注解,它是Guice提供的标注在类上的注解,用于简化绑定,他俩可以标注在接口上。


  • @ImplementedB:注解用于简化绑定配置,通常用于指定默认的实现类型。最常用的场景在于编写 Dao 或者 Service 时,指定 Interface 的实现类。
  • @ProvidedBy:作用同上,只不过是通过Provider方式来提供


@ImplementedBy(Dog.class)
// @Singleton // 不能标记在接口上,只能标记在Dog实现类上
public interface Animal {
    void run();
}
@Test
public void fun1() {
  // 注意:并不需要使用使用模块,注解就行哦~~
    Injector injector = Guice.createInjector();
    injector.injectMembers(this);
    System.out.println(animal);
    System.out.println(injector.getInstance(Animal.class));
    System.out.println(injector.getInstance(Animal.class));
    animal.run();
}


这样标注后效果完全同:

bind(Animal.class).to(Dog.class)


@ProvidedBy就不用演示了,它的效果同:

bind(Animal.class).toProvider(DogProvider.class)



Guice和Spring Boot整合


作为主流的微服务开发框架Spring Boot,可以说Guice不可能撼动Spring的江湖地位,其实它也无意去撼动它,乖乖的专心做自己的DI就好。


那么如果一个开源的库是用Guice构建的,而你想在Spring Boot环境下使用肿么办呢???那就是整合。他俩并发冲突,反而也可以一起协作,总的思想有点类似于Spring MVC和Spring的协作:MVC负责请求控制,而Spring负载从当IoC容器,负责DI依赖注入。


当然喽,他俩的集成做不到那么的浑然天成, 思考的思路是:向Spring Boot容器内注入的业务Bean请不要new,请不要new,请不要new,而是通过injector.getInstance(xxx)从Guice里拿,这样便完成了整合。总之就是各自做各自的事,然后通过某个“接口”来完成融合即可,比如这里用Spring Boot总控(其实就是MVC),然后Guice负责管理业务对象之间的依赖关系(如Service、Dao等)。


另外,在web下使用/整合Guice,一般需要导入下面Jar包给与支持:


<dependency>
    <groupId>com.google.inject.extensions</groupId>
    <artifactId>guice-servlet</artifactId>
    <version>4.1.0</version>
</dependency>


Tips:整合过程中,请一定一定一定要注意对象的生命周期以及Scope(Spring Boot一般要单例,而Guice需要做特殊的满足哦~~~)


Guice vs Spring


虽然这两者没有太大的可比性,但由于都是DI框架,所以做一个简单的比较吧。


  • Spring不仅仅是DI,它是一个全家桶技术总和;Guice是个轻量级的DI框架,只聚焦于依赖的管理、注入
  • Spring的配置文件(xml or Confiuration以及扫描的)体现了完整的装配结构;Guice使用Java代码来描述绑定关系
  • Spring使用字符串来表示Bean的key;Guice一般使用类型绑定关系来描述一个实例,且是分模块的、局部的
  • Spring在容器初始化时候完成所有关系的绑定;Guice只记录绑定关系,然后在运行时有需要的时候帮你完成注入
  • 优缺点
  • Spring 的优缺点此处不做说明,主要描述Guice它的DI领域的优缺点。


  • 优点
  • 轻量级(代码量少)
  • 性能优异
  • 良好的泛型支持
  • 因为都用Java语言绑定,所以是强类型的,不容易出错
  • 易于重构Refactor(也得益于是Java代码的强类型)
  • 缺点
  • 学习成本颇高,学习曲线相对陡峭
  • Module的众多绑定规则不太容易理解,导致出错了不易排查
  • 教程少,文档少,中文文档、案例就更少了
  • 社区活跃度无法同Spring相提并论
  • 无法解决循环依赖注入的问题
  • 此问题官方认为不是问题,因为官方建议你通过别的方式避免循环依赖(说明:Spring是解决了循环依赖注入问题的)
  • 编译器支持相对差些(比如它的Guice的AOP不能方便的跳转)


总之,Spring大而全,Guice小而美。企业级应用当然还是推荐使用Spring,而如果你是自己写写组件,不妨用Guice去管理的依赖吧,它能让你的代码结构更加优美且显得不那么臃肿。


当然,理想归理想,说去真心话国内的Java技术毕竟还是阿里这种大厂主导,而非Google系,因此实际生产中若你要使用请三思而后行,毕竟你还有同伴~


总结


关于轻量级依赖注入框架Google Guice就先介绍到这了,相信通过本文的学习,你只需要花几分钟的时间就能了解到Guice的几乎全貌了。


我个人意见,此门DI技术不用深究,但却有必要了解,因为文首说了有些流行的开源框架是基于它构建的,所以了解Guice才能更好的阅读学习其源码。

相关文章
|
29天前
|
Java 数据库
在Java中使用Seata框架实现分布式事务的详细步骤
通过以上步骤,利用 Seata 框架可以实现较为简单的分布式事务处理。在实际应用中,还需要根据具体业务需求进行更详细的配置和处理。同时,要注意处理各种异常情况,以确保分布式事务的正确执行。
|
29天前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
1月前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
138 3
|
24天前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
35 4
|
1月前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
1月前
|
消息中间件 Java 数据库连接
Java 反射最全详解 ,框架设计必掌握!
本文详细解析Java反射机制,包括反射的概念、用途、实现原理及应用场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Java 反射最全详解 ,框架设计必掌握!
|
1月前
|
开发框架 Java 关系型数据库
Java哪个框架适合开发API接口?
在快速发展的软件开发领域,API接口连接了不同的系统和服务。Java作为成熟的编程语言,其生态系统中出现了许多API开发框架。Magic-API因其独特优势和强大功能,成为Java开发者优选的API开发框架。本文将从核心优势、实际应用价值及未来展望等方面,深入探讨Magic-API为何值得选择。
46 2
|
1月前
|
前端开发 Java 数据库连接
你不可不知道的JAVA EE 框架有哪些?
本文介绍了框架的基本概念及其在编程领域的应用,强调了软件框架作为通用、可复用的软件环境的重要性。文章分析了早期Java EE开发中使用JSP+Servlet技术的弊端,包括可维护性差和代码重用性低等问题,并阐述了使用框架的优势,如提高开发效率、增强代码规范性和可维护性及提升软件性能。最后,文中详细描述了几种主流的Java EE框架,包括Spring、Spring MVC、MyBatis、Hibernate和Struts 2,这些框架通过提供强大的功能和支持,显著提升了Java EE应用的开发效率和稳定性。
68 1
|
1月前
|
JSON 自然语言处理 Java
这款轻量级 Java 表达式引擎,真不错!
AviatorScript 是一个高性能、轻量级的脚本语言,基于 JVM(包括 Android 平台)。它支持数字、字符串、正则表达式、布尔值等基本类型,以及所有 Java 运算符。主要特性包括函数式编程、大整数和高精度运算、完整的脚本语法、丰富的内置函数和自定义函数支持。适用于规则判断、公式计算、动态脚本控制等场景。
|
1月前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
47 0