Google Guice - 轻量级 DI 依赖注入框架

Guice简单使用

示例代码 Anddd7/Demo-Guice

参考了 博客 - Google Guice 系列教程 和 Github - greengerong/guice-demo

Guice是一个DI (依赖注入) 框架 ,和Spring的依赖注入基本相同

  • 轻量级 ,启动迅速
  • 使用比较简单

但是

  • 只有依赖注入的功能 ,如果是企业级的程序 ,需要整合其他资源 ,Spring的生态圈还是好很多的

开始

  • 引入依赖@Inject ,同Spring @Autowired
public class MessageServiceImpl implements MessageService {

    @Inject
    MessageDao messageDao;

    public void sendMessage(Message msg) {
        messageDao.sendMessage(msg);
    }

    public Message receiveMessage() {
        return messageDao.receiveMessage();
    }
}
  • 注入对象 @Provide ,同Spring @Bean ; 同时会将方法中包含的其他对象注入(nameService1,nameService2)
@Provides
public List<BookService> getAllItemServices(@Named("book1") BookService nameService1, @Named("book2") BookService nameService2) {
    return of(nameService1, nameService2);
}
  • 依赖管理 AbstractModule ,Spring是通过扫描注解 ,Guice则是按照模块手动控制
/**
 * Message模块 依赖管理
 * 绑定接口和实现
 */
public class MessageModule extends AbstractModule {

    protected void configure() {
        final Binder binder = binder();
        //interface-impl 依赖关系
        binder.bind(MessageService.class).to(MessageServiceImpl.class).in(SINGLETON);
        binder.bind(MessageDao.class).to(MessageDaoImpl.class).in(SINGLETON);

        //单独注入 ,单例
        binder.bind(SingleScopeBean.class).in(SINGLETON);
        binder.bind(NoScopeBean.class).in(NO_SCOPE);

        //可以将已经引入的对象绑定到容器中
        binder.bind(HelloWorld.class).toInstance(helloWorld);
    }

    private HelloWorld helloWorld;

    public MessageModule(HelloWorld helloWorld) {
        this.helloWorld = helloWorld;
    }
}
  • 多实现
/**
 * User模块 依赖管理
 * <p>
 * 一个interface是无法绑定不同的impl的 ,可以通过两种方式
 *      使用Multibinder
 *      使用注解别名区别
 */
public class UserModule extends AbstractModule {

    protected void configure() {
        final Binder binder = binder();

        //具有多个实现的service ,会以 Set<UserService> 存在
        final Multibinder<UserService> userServiceMultibinder = Multibinder.newSetBinder(binder, UserService.class);
        userServiceMultibinder.addBinding().to(EmployeeServiceImpl.class);
        userServiceMultibinder.addBinding().to(EmployerServiceImpl.class);

        //通过名称绑定
        binder.bind(BookService.class).annotatedWith(Names.named("book1")).to(Book1ServiceImpl.class);
        binder.bind(BookService.class).annotatedWith(Names.named("book2")).to(Book2ServiceImpl.class);
    }

    /**
     * 同@Bean ,将返回值作为一个容器对象
     */
    @Provides
    public List<BookService> getAllItemServices(@Named("book1") BookService nameService1, @Named("book2") BookService nameService2) {
        return of(nameService1, nameService2);
    }
}

使用

public class AppBindTest {

    private static final Logger log = LoggerFactory.getLogger(AppBindTest.class);

    private Injector injector;
    /**
     * 创建module(相当于 bean 工厂) ,可加载多个
     */
    @Before
    public void setUp() throws Exception {
        injector = Guice.createInjector(
                new MessageModule(new HelloWorld("Test 初始化")),//这里的HelloWorld是手动创建 再关联到容器中的
                new UserModule());
    }

    /**
     * 测试绑定已有对象 ,HelloWorld
     */
    @Test
    public void runtimeTest() throws Exception {
        HelloWorld instance = injector.getInstance(HelloWorld.class);
        HelloWorld instance2 = injector.getInstance(HelloWorld.class);

        Assert.assertEquals(instance, instance2);
    }

    /**
     * 测试依赖注入 @Inject ,通过接口取用 ; Service中包含了Dao
     */
    @Test
    public void injectTest() throws Exception {
        MessageService instance = injector.getInstance(MessageService.class);
        instance.sendMessage(new Message("send", "土豆土豆 ,我是地瓜"));

        Message receive = instance.receiveMessage();
        log.debug(receive.toString());

        Assert.assertThat(instance, is(instanceOf(MessageServiceImpl.class)));
    }

    /**
     * 测试单例 Singleton
     */
    @Test
    public void singletonTest() throws Exception {
        SingleScopeBean instance = injector.getInstance(SingleScopeBean.class);
        SingleScopeBean instance2 = injector.getInstance(SingleScopeBean.class);

        log.debug(instance.toString());
        log.debug(instance2.toString());

        Assert.assertEquals(instance, instance2);
    }

    /**
     * 测试非单例 NoScope
     */
    @Test
    public void noScopeTest() throws Exception {
        NoScopeBean instance = injector.getInstance(NoScopeBean.class);
        NoScopeBean instance2 = injector.getInstance(NoScopeBean.class);

        log.debug(instance.toString());
        log.debug(instance2.toString());
        Assert.assertNotEquals(instance, instance2);
    }

    /**
     * 测试多重绑定 ,取出的是一个Set
     */
    @Test
    public void multiBindTest() throws Exception {
        Set<UserService> instances = injector.getInstance(
                new Key<Set<UserService>>() {
                });

        List<User> users = new ArrayList<User>();
        instances.forEach(e -> users.addAll(e.getUser()));

        users.forEach(e -> log.debug(e.toString()));

        Assert.assertEquals(4, users.size());
    }

    /**
     * 测试 @Provide 装配的对象
     */
    @Test
    public void provideTest() throws Exception {
        List<BookService> instances = injector.getInstance(new Key<List<BookService>>() {
        });
        instances.forEach(e -> log.debug(e.info()));

        Assert.assertEquals(2, instances.size());
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值