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

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

前言


说起依赖注入(DI),相信你首先想到的必然是Spring,Spring是Java技术全家桶,是Java EE开发的一站式解决方案和实际开发标准。但本文并不聊它,而是介绍一款谷歌开源的轻量级依赖注入框架:Guice。


Guice在Java领域并不流行(相较于Spring),但因为它轻量级,所以可以作为你去学习理解DI的一个抓手,适合你去进行独立的分析和理解依赖注入的思想,毕竟程序员经常说的:思想都是相通的。


另外,学习它还有一个重要原因是有些流行框架/库使用了它作为基础DI库,如:Druid、Elastic Search、Play2以及我们熟悉的携程开源的Apollo和Netflix的Eureka。


正文


正所谓谷歌出品,必属精品,况且Guice还出自于它的广告这种多金部门,自然也不例外。Google Guice被大量应用于谷歌内部,然后2010年开源出来。虽然业界反响并不大,但是因为它的轻量级,有些流行的开源框架(如Druid、Apollo、Elastic Search、Play2)把它作为基础的DI组件。


轻量级是什么意思?


轻量级是一个相对概念,它至少应该有如下特征:


  1. 代码少
  2. 易维护
  3. 性能优异


Google Guice就是这么一个框架,它特别强调它的Lightweight特性。


Google Guice


Google Guice作为一个纯粹的DI框架,主要用于减轻你对工厂的需求以及Java代码中对new的使用。通过它来构建你的代码,能减少依赖,从而使得更容易更改以及更容易单元测试和重用。


下面我们就研究它的特性,然后辅以一定的代码示例对它展开基础学习。

公用基础代码


导包:

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


基础代码:


public interface Animal {
    void run();
}
public class Dog implements Animal {
    @Override
    public void run() {
        System.out.println("dog run...");
    }
}
public class Cat implements Animal {
    @Override
    public void run() {
        System.out.println("run run...");
    }
}


DI配置类(模块):


public class MainModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(Animal.class).to(Dog.class);
    }
}


测试类:


public class TestGuice {
    @Inject
    private Animal animal;
   官方推荐使用构造器注入,但本类是测试类,为了方便就使用属性注入喽
   当然喽,test类必须有空构造器~~~~这就另说了
  //@Inject
  //public TestGuice(Animal animal){
  //  this.animal = animal;
  //}
    @Test
    public void fun1(){
        Injector injector = Guice.createInjector(new MainModule());
        // 为当前实例注入容器内的对象
        injector.injectMembers(this);
        System.out.println(animal);
        System.out.println(injector.getInstance(Animal.class));
        System.out.println(injector.getInstance(Animal.class));
        animal.run();
    }
}


运行程序,控制台打印:

com.yourbatman.eurekaclient.guice.Dog@6fb0d3ed
com.yourbatman.eurekaclient.guice.Dog@24b1d79b
com.yourbatman.eurekaclient.guice.Dog@68ceda24
dog run...


这便是一个最简单的使用Guice来实现依赖注入的示例,和Spring的ApplicationContext还蛮像的有木有。针对此实例的输出,你应该也意识到此处一个非常非常不一样的不同:默认是多例的(每次get/注入的都是不同的实例)。


如何保证单例?


不同于Spring,它默认是多例的,因此需要我们做一些事情来保证单例。


1、使用@Singleton注解

@Singleton
public class Dog implements Animal { ... }


说明:该注解只能标注在实现类上,不能标注在接口/抽象类上


2、绑定时指定单例

bind(Animal.class).to(Dog.class).in(Singleton.class);


3、绑定一个现存的实例

bind(Animal.class).toInstance(new Dog());


以上三种方式处理后,使用依赖注入或者用API injector.getInstance()得到的均会是同一个实例对象,这就是单例了。


绑定

任何需要依赖注入的资源,只有先实现了绑定才能注入,本处开始介绍它的绑定方式。


  • 类名绑定:把实现类绑定到接口(当然也可以实现类绑到实现类),具体实例交给框架去帮你创建


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


  • 实例绑定:绑定一个现有实例


bind(Animal.class).toInstance(new Dog())



注意:采用这种绑定,依赖注入时永远是单例(也就是这个实例)

  • 连接绑定:对于已经绑定了的关系,可以无限一直连接下去


bind(Animal.class).to(Dog.class);
bind(Dog.class).toInstance(new Dog(){
    @Override
    public void run() {
        System.out.println("son dog");
        super.run();
    }
});


  • Provider绑定:类似于Spring的@Bean注解,适合完成需要编程逻辑完成的实例
见基础代码,略。


  • 泛型绑定:支持泛型类型的绑定。借助TypeLiteral来完成
bind(new TypeLiteral<List<Animal>>(){}).toInstance(Arrays.asList(new Dog(),new Cat()));
• 1


集合绑定:可在不同的Module内向同一个集合分别去绑定自己所要支持的内容,当然喽也可以在同一个Module内


Multibinder<Animal> multibinder = Multibinder.newSetBinder(binder(), Animal.class);
multibinder.addBinding().toInstance(new Dog());
multibinder.addBinding().toInstance(new Cat());


说明:依赖于扩展包guice-multibindings,需要导入这个jar才行





相关文章
|
11月前
|
人工智能 Java 开发者
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
JManus是阿里开源的Java版OpenManus,基于Spring AI Alibaba框架,助力Java开发者便捷应用AI技术。支持多Agent框架、网页配置、MCP协议及PLAN-ACT模式,可集成多模型,适配阿里云百炼平台与本地ollama。提供Docker与源码部署方式,具备无限上下文处理能力,适用于复杂AI场景。当前仍在完善模型配置等功能,欢迎参与开源共建。
3472 58
阿里出手!Java 开发者狂喜!开源 AI Agent 框架 JManus 来了,初次见面就心动~
|
10月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
10月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
851 8
|
10月前
|
存储 算法 安全
Java集合框架:理解类型多样性与限制
总之,在 Java 题材中正确地应对多样化与约束条件要求开发人员深入理解面向对象原则、范式编程思想以及JVM工作机理等核心知识点。通过精心设计与周密规划能够有效地利用 Java 高级特征打造出既健壮又灵活易维护系统软件产品。
246 7
|
10月前
|
存储 安全 Java
《数据之美》:Java集合框架全景解析
Java集合框架是数据管理的核心工具,涵盖List、Set、Map等体系,提供丰富接口与实现类,支持高效的数据操作与算法处理。
|
12月前
|
存储 缓存 安全
Java集合框架(二):Set接口与哈希表原理
本文深入解析Java中Set集合的工作原理及其实现机制,涵盖HashSet、LinkedHashSet和TreeSet三大实现类。从Set接口的特性出发,对比List理解去重机制,并详解哈希表原理、hashCode与equals方法的作用。进一步剖析HashSet的底层HashMap实现、LinkedHashSet的双向链表维护顺序特性,以及TreeSet基于红黑树的排序功能。文章还包含性能对比、自定义对象去重、集合运算实战和线程安全方案,帮助读者全面掌握Set的应用与选择策略。
1397 23
|
11月前
|
SQL Java 数据库连接
区分iBatis与MyBatis:两个Java数据库框架的比较
总结起来:虽然从技术角度看,iBATIS已经停止更新但仍然可用;然而考虑到长期项目健康度及未来可能需求变化情况下MYBATISS无疑会是一个更佳选择因其具备良好生命周期管理机制同时也因为社区力量背书确保问题修复新特征添加速度快捷有效.
886 12
|
安全 Java 开发者
Java集合框架:详解Deque接口的栈操作方法全集
理解和掌握这些方法对于实现像浏览器后退功能这样的栈操作来说至关重要,它们能够帮助开发者编写既高效又稳定的应用程序。此外,在多线程环境中想保证线程安全,可以考虑使用ConcurrentLinkedDeque,它是Deque的线程安全版本,尽管它并未直接实现栈操作的方法,但是Deque的接口方法可以相对应地使用。
545 12
|
12月前
|
存储 缓存 安全
Java集合框架(三):Map体系与ConcurrentHashMap
本文深入解析Java中Map接口体系及其实现类,包括HashMap、ConcurrentHashMap等的工作原理与线程安全机制。内容涵盖哈希冲突解决、扩容策略、并发优化,以及不同Map实现的适用场景,助你掌握高并发编程核心技巧。
|
12月前
|
存储 安全 Java
Java集合框架(一):List接口及其实现类剖析
本文深入解析Java中List集合的实现原理,涵盖ArrayList的动态数组机制、LinkedList的链表结构、Vector与Stack的线程安全性及其不推荐使用的原因,对比了不同实现的性能与适用场景,帮助开发者根据实际需求选择合适的List实现。
1289 0

热门文章

最新文章