Google-Guice入门教程

Guice简介

Guice是Google出品的一款轻量级DI框架,Elasticsearch就使用了Guice。说到DI,离不开Spring。在Guice的Wiki上写着 While Spring is a comprehensive stack, Guice focuses on dependency injection
  Spring不是今天的主角,开始正文吧。

Guice的优点

  1. 速度快,号称比spring快100倍。(摘抄,但是感觉所说的快就是启动的时候,不是指运行时)
  2. 无外部配置(如需要使用外部可以可以选用Guice的扩展包),完全基于annotation特性,支持重构,代码静态检查。
  3. 简单,快速,基本没有学习成本。 个人感觉Guice有很多地方和Spring是有点像的,它的wiki中也写到他们在开发的时候是给Spring的开发团队看过Guice源码,也借鉴了一些东西。

快速开始

Guice的注入非常方便,不需要配置文件。开始demo 首先引入依赖

 Gradle
 compile "com.google.inject:guice:4.1.0
 
 Maven
 <dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>4.1.0</version>
 </dependency>
复制代码
// 被依赖的dao
@Singleton // 打上了这个标记说明是单例的,否则Guice每次回返回一个新的对象
public class UserDao{
   public void say(){
        System.out.println("dao is saying");
   }
}

// service,依赖 UserDao
public class UserService {

    @Inject
    private UserDao mUserDao;

    public void say() {
        return mUserDao.say();
    }
}

// 启动类
public class Start  {
   public static void main(final String[] args) {
        //这步就是我们问Guice去要对象
        final Injector injector = Guice.createInjector();
        final UserService userService = injector.getInstance(UserService.class);
        userService.say();
    }
}

结果输出:dao is saying
复制代码

可以看到没有任何的xml配置,唯一需要做的,就是在需要注入的属性上,打上**@inject**。 使用 Guice.createInjector()启动。通常需要尽早在程序中创建注入器。这样 Guice 能够帮助您创建大部分对象 Guice中可以实现依赖注入,并且完全可以正常的运行(感觉这个破坏了分层,暂时没发现这个在什么场景会用到?)

注入

在Guice中,注入和绑定是分开的,先来讲注入。 注入的方式

  1. 构造函数注入 这个和Spring中的一样,如下即可
public class UserService {

    private UserDao mUserDao;

    @Inject
    public UserService(UserDao userDao) {
        this.mUserDao = userDao;
    }

    public void say() {
        mUserDao.say();
    }
}
复制代码
  1. 方法注入 可以理解为Spring的setter注入,但是Guice不关心这个方法的名称、访问修饰符、参数个数、返回值等,它只关心,这个方法上是否有@inject注解,比如下面这种奇怪的写法,也是可以被注入的 eg.
    @Inject 
    private Long injectDao(UserDao userDao) {
        this.userdao = user dao 
    }
复制代码
  1. 字段注入 快速开始中就是使用这个来注入的,跳过。

绑定

这是一张Guice绑定的结构图,作为参考

上面图中引入了Module, Module是一个特殊的类,用于告诉 Guice 具体使用哪个依赖项。简单的说,用来绑定各个接口对应的实现。在之前的demo中,并没有用到Module,也成功运行了,是因为之前没有设计到接口,当只是依赖确切的实现类的时候,Guice会自动的找到需要注入的实现类

先来看看对于同一个接口的具有多个实现类的绑定,代码如下

// 先来一个接口
public interface IAnimal {
    void talk();
}

// 实现类dog
public class Dog implements IAnimal {
    @Override
    public void talk() {
        System.out.println("i am dog!");
    }
}

// 实现类 SuperDog
public class SuperDog implements IAnimal {
    @Override
    public void talk() {
        System.out.println("i am super dog");
    }
}

// 这个类有点类似于Spring的Qualife
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.PARAMETER })
@BindingAnnotation
public @interface Super {
}

// service
public class AnimalService {

    @Inject
    private IAnimal dog;

    //打上了@Super的注解,Guice在注入的时候会根据在Module里面配置的绑定关系注入对应的实现类
    @Inject  @Super
    private IAnimal superDog;

    public void talk() {
        System.out.println("dog will talk");
        dog.talk();
        System.out.println("super will talk");
        superDog.talk();
    }
}

// 这里就是绑定逻辑的地方
public class AnimalModule extends AbstractModule {
    @Override
    protected void configure() {
        // 这行的意思即是把Dog绑定给IAnimal
        bind(IAnimal.class).to(Dog.class);
        // 下面
        bind(IAnimal.class).annotatedWith(Super.class).to(SuperDog.class);
    }
}

// 运行
public class MainStart {

    public static void main(final String[] args) {
        final Injector injector = Guice.createInjector(new AnimalModule());
        final AnimalService animalService = injector.getInstance(AnimalService.class);
        animalService.talk();
    }
    
运行上面的代码,最终会输出:
dog will talk
i am dog!
super will talk
i am super dog
复制代码

关键的地方只有

  1. IAnimal 具有两个不同的实现类 Dog 和SuperDog
  2. @Super 注解必须带有 @BindingAnnotation,否则Guice会报错
  3. AnimalModule 中重写的 configure() 方法,这里面维护了一个绑定的关系
  4. 如果在接口上打上@ImplementedBy(XXX.class)接口,Guice 会把 XXX.class作为该接口的默认实现类处理

转载于:https://juejin.im/post/5a375e156fb9a0452a3c6b96

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值