Guice

在上一篇博客中, 我们讲解了Spring中的IOC示例与实现, 本文着重介绍Guice注入以及与Spring中的差异.

Guice是Google开发的, 一个轻量级的依赖注入框架, 跟Spring最大的区别在于脱离xml配置,

大量使用Annotation来实现注入, 支持属性, 构造器, setter等多种方式注入对象.

Guice 3.0支持 jdk 1.6, 如果运行报错ClassNotFoundException: javax.inject.Provider, 则需要导入javax.inject包.

Module容器

Guice中容器即Module, 用于绑定接口 : 实现类, 类似于Spring中的applicationContext.xml.

Module像是一个Map,根据一个Key获取其Value,清楚明了的逻辑.

以下代码实现了一个简单的注入

         Injector ij = Guice.createInjector(new Module() {
@Override
public void configure(Binder binder) {
binder.bind(TestService.class).to(ServiceImpl.class);
}
});
ij.getInstance(TestService.class).test();

支持绕过Module, 用默认配置, 直接实例化对象, 不过没啥意义, 除非要用容器做aop

         Injector ij2 = Guice.createInjector();
ij2.getInstance(ServiceImpl.class).test();

当然也可以使用注解的方式来声明接口的实现类, 然后Injector 从接口中获取对象,

意义也不大, 因为实际业务中, 接口可能在上层包里, 无法直接调用实现类.

 @ImplementedBy(ServiceImpl.class)
public interface TestService { void test();
} --------------------------------------- Injector ij3 = Guice.createInjector();
10 ij3.getInstance(TestService.class).test();

@Inject属性注入

 public class GuiceObjectDemo {

     @Inject
private TestService service1;
@Inject
private TestService service2; --------------------------------------- GuiceObjectDemo demo = Guice.createInjector().getInstance(GuiceObjectDemo.class);
System.out.println(demo.getService());
System.out.println(demo.getService2());

属性注入的时候, 必须通过Guice.createInjector().getInstance(GuiceObjectDemo.class);来获取实现类, 如果直接new的话, 会inject失败, 打印出两个null.

这是因为如果对象不属于Guice托管, 那么他也无法得到Guice注入.

如果一定要new GuiceObjectDemo()呢? 没关系, 还有另外一种写法可以满足.

         GuiceObjectDemo demo1 = new GuiceObjectDemo();
Guice.createInjector().injectMembers(demo1);
System.out.println(demo1.getService());

静态属性注入

调用binder.requestStaticInjection

         Guice.createInjector(new Module() {
@Override
public void configure(Binder binder) {
binder.requestStaticInjection(GuiceObjectDemo.class);
}
});
System.out.println(GuiceObjectDemo.getService3());

普通属性也可以通过该方法注入, 只要把binder那边改成requestInjection即可.

构造函数注入

     @Inject
public GuiceObjectDemo(TestService service1, TestService service2) {
this.service1 = service1;
this.service2 = service2;
}

构造函数会自动注入多个参数, 因此只要写一个@Inject即可.

如果有多个构造函数, 只能在一个构造函数上加Inject, 不然会报错

has more than one constructor annotated with @Inject

同理Setter注入, 只要在setXX方法上加上@Inject标签即可实现赋值.

动态参数注入

这个稍微麻烦一点, 需要引入guice-assistedinject, 利用FactoryModuleBuilder构造一个factory实行注入.

实际业务场景中, 大部分构造函数的参数是动态从外部传递进来的, 并不是直接new出来的.

 public class ServiceImpl implements TestService{

     private String member;

     @Inject
public ServiceImpl(@Assisted String member) {
// 利用Assisted注解, 动态注入参数
this.member = member;
} public void setMember(String member) {
this.member = member;
} @Override
public String toString() {
return "ServiceImpl Memeber: " + member;
}
}
---------------------------------------
public interface TestService { }
---------------------------------------
public interface PageFactory { ReportPageProvider createReportPage(ResultReport report); }
---------------------------------------
public class IOCDemo { public static void main(String[] args){
Module module = new com.fr.third.inject.Module() {
@Override
public void configure(Binder binder) {
binder.install(new FactoryModuleBuilder()
.implement(TestService.class, ServiceImpl.class)
.build(ImplFactory.class)
);
}
}; Injector injector = Guice.createInjector(module);
ImplFactory factory = injector.getInstance(ImplFactory.class);
TestService impl = factory.create("neil123");
System.out.println(impl);
} }

有多个实现类的接口

此时通过上文直接写单个@Inject或者Module都无法实现, 需要引入自定义注解, 或者Names方法.

 public class GuiceObjectDemo {

     @Inject
@Named("A")
private TestService service1;
@Inject
@Named("B")
private TestService service2; --------------------------------------- final GuiceObjectDemo demo1 = new GuiceObjectDemo();
Guice.createInjector(new Module() {
@Override
public void configure(Binder binder) {
binder.bind(TestService.class).annotatedWith(Names.named("A")).to(ServiceImplA.class);
binder.bind(TestService.class).annotatedWith(Names.named("B")).to(ServiceImplB.class);
binder.requestInjection(demo1);
}
});
System.out.println(demo1.getService());
System.out.println(demo1.getService2());

如果不用Named注解, 则可以通过自定义注解, 其他写法都一样

                  binder.bind(TestService.class).annotatedWith(ImplA.class).to(ServiceImplA.class);
binder.bind(TestService.class).annotatedWith(ImplB.class).to(ServiceImplB.class);

Provider注入

其实就是类似于工厂注入,  对象不是直接new接口的实现类, 而是由工厂提供.

 public class ServiceFactory implements Provider<TestService> {

     @Override
public TestService get() {
return new ServiceImpl();
} } --------------------------------------- @ProvidedBy(ServiceFactory.class)
public interface TestService { void test();
} --------------------------------------- GuiceObjectDemo demo = Guice.createInjector().getInstance(GuiceObjectDemo.class);
System.out.println(demo.getService());

Scope

可以通过在impl类上加@Singleton来实现单例, 也可在module中管理

  binder.bind(TestService.class).to(ServiceImpl.class).in(Scopes.SINGLETON);

默认单例模式的对象, 是在第一次使用的时候才初始化, 也可以通过设置asEagerSingleton, 注入到容器后立刻初始化.

         Injector in = Guice.createInjector(new Module() {
@Override
public void configure(Binder binder) {
// 调用getInstance才初始化impl
binder.bind(ServiceImpl.class);
// 注入到容器后立刻初始化impl
// binder.bind(ServiceImpl.class).asEagerSingleton();
}
});
Thread.sleep(3000);
in.getInstance(ServiceImpl.class).test();

到这边就结束了, 通过上面的案例不难看出, , 相比于Spring IOC, Guice是一个非常轻量灵活的注入实现, 0 xml.

Guice之IOC教程的更多相关文章

  1. Guice 4.1教程

    Guice是Google开发的一个开源轻量级的依赖注入框架,运行速度快,使用简单. 项目地址:https://github.com/google/guice/ 最新的版本是4.1,本文基于此版本. 0 ...

  2. 使用Dagger2做静态注入, 对比Guice.

    Dagger 依赖注入的诉求, 这边就不重复描述了, 在上文Spring以及Guice的IOC文档中都有提及, 既然有了Guice, Google为啥还要搞个Dagger2出来重复造轮子呢? 因为使用 ...

  3. 轻量级IOC框架:Ninject (上)

    前言 前段时间看Mvc最佳实践时,认识了一个轻量级的IOC框架:Ninject.通过google搜索发现它是一个开源项目,最新源代码地址是:http://github.com/enkari/ninje ...

  4. Guice总结

    Guice总结 Jar包:guice-4.1.0.jar 辅包: guava-15.0.jar aopalliance-.jar javaee-api-6.0-RC2.jar Guice的IoC 两种 ...

  5. 58 web框架Argo代码分析

    贴地址:https://github.com/58code/Argo 核心jar javax.servlet-api 3.0.1 guice 3.0 velocity 1.7 框架使用 servlet ...

  6. Ninject学习笔记<四>

    前言 前段时间看Mvc最佳实践时,认识了一个轻量级的IOC框架:Ninject.通过google搜索发现它是一个开源项目,最新源代码地址是:http://github.com/enkari/ninje ...

  7. 深入浅出微服务框架dubbo(一):基础篇

    一.基础篇 1.1 开篇说明 dubbo是一个分布式服务框架,致力于提供高性能透明化RPC远程调用方案,提供SOA服务治理解决方案.本文旨在将对dubbo的使用和学习总结起来,深入源码探究原理,以备今 ...

  8. java轻量级IOC框架Guice

    Google-Guice入门介绍(较为清晰的说明了流程):http://blog.csdn.net/derekjiang/article/details/7231490 使用Guice,需要添加第三方 ...

  9. 轻量级IOC框架Guice

    java轻量级IOC框架Guice Guice是由Google大牛Bob lee开发的一款绝对轻量级的java IoC容器.其优势在于: 速度快,号称比spring快100倍. 无外部配置(如需要使用 ...

随机推荐

  1. 走近 Python (类比 JS)

    Python 是一门运用很广泛的语言,自动化脚本.爬虫,甚至在深度学习领域也都有 Python 的身影.作为一名前端开发者,也了解 ES6 中的很多特性借鉴自 Python (比如默认参数.解构赋值. ...

  2. Ubuntu下通过makefile生成静态库和动态库简单实例

    本文转自http://blog.csdn.net/fengbingchun/article/details/17994489 Ubuntu环境:14.04 首先创建一个test_makefile_gc ...

  3. Codeforces Round #203 (Div. 2)B Resort

    Resort Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  4. 使用javascript编写根据用户鼠标控制背景图片的移动

    在一家VR公司做前端. 起初进入前端就是一种内心的直觉,创造更好的用户体验,让页面更加友好,当然最起初接手web项目还是为了完成毕业设计. 一个网上图书商城,虽然不大,但五脏都有毕竟开刀所以避免不了很 ...

  5. 从成本角度看Java微服务

    近年来,微服务因其良好的灵活性和伸缩性等特点备受追捧,很多公司开始采用微服务架构或将已有的单体系统改造成微服务.IBM也于近日开源了轻量级Java微服务应用服务器 Open Liberty .但是采用 ...

  6. MQTT——发布报文

    发布报文的知识点并不难,只是多.看过前面几章的读者们应该或多或少都认识服务质量QOS.发布报文跟他的联系最紧的.我们也清楚订阅报文里面虽然也有用到QOS,但是他却没有更进一步的联系.往下看就知道是什么 ...

  7. Spring Security Ajax 被拦截

    背景是项目中使用Spring Security 进行安全控制 再使用Ajax的时候会报 403(ajax get  方式是没问题的 post 的时候会报) Spring Security 原本是 防止 ...

  8. 百度地图Marker优化方案

    简介 在使用百度地图的时候,我们需要在地图上增加标注Marker来展示设置信息.随着用户需要不断增多,加载更多的Marker标注信息成为了一种奢望.然而通过自己技术的提升,归结出来了一下方案. 引入百 ...

  9. Git提交到github上

    1.本地创建一个目录redis [guosong@etch171 mars171 redis]# pwd /data1/guosong/code/redis [guosong@etch171 mars ...

  10. 前端设计师如何提高UI界面中的阅读性

    阅读体验是ui设计中必不可少的一项,良好的设计应该都是可读的设计,如果信息都无法正常而清晰的传达,那么设计就失去了意义.设计的可读性和排版设计息息相关,这也就跟设计师的设计功底息息相关.下面简单介绍文 ...