• Google Guice之作用域


    默认情况下,Guice获取一个实例时。每次都会返回一个新的对象。

    这个行为能够通过scopes进行配置。Scopes同意你复用实例:
    应用整个生命周期(@Singleton),会话(@Session),请求(@RequestScoped),Guice还提供为Web应用提供了一种Servlet扩展作用域。而且在Guice还能够自己定义范围。



    Guice使用注解来标识作用域,将注解加入到某一类型的实现类上:


    @Singleton
    public class InMemoryTransactionLog implements TransactionLog {
      /* everything here should be threadsafe! */
    }

    作用域也能够使用bind语句进行配置:


    bind(TransactionLog.class).to(InMemoryTransactionLog.class).in(Singleton.class);

    @Provides方法加入作用域注解:

    @Provides @Singleton
    	TransactionLog provideTransactionLog() {
    	...
    }

    假设在配置作用域时,使用注解与bind()语句存在冲突,那么以bind()中的配置为准。假设某一类型不想指定作用域则能够使用
    Scopes.NO_SCOPE.
    在链接绑定中,作用域是应用于绑定源上,而不是应用了绑定目标上。假如我们有一个Appleess类实现了Bar和Grill接口,
    以下的绑定配置就存在两个实例。一个用于Bar。还有一个用于Grill:

    bind(Bar.class).to(Applebees.class).in(Singleton.class);
    bind(Grill.class).to(Applebees.class).in(Singleton.class);

    这是由于作用域应用于绑定源(Bar,Grill),而不是绑定目标(Appless)。假设要求仅仅创建一个实例,则能够在Appless类上加入@Singleton注解。或者再加入一个绑定配置:

    bind(Applebees.class).in(Singleton.class);
    该绑定配置就使得两个.in(Singleton.class)语句变得多余了。in()语句不仅能够接收一个Scope注解,如RequestScope.class 。还能够接收Scope实例,如ServletScopes.REQUEST:

    bind(UserPreferences.class)
          .toProvider(UserPreferencesProvider.class)
          .in(ServletScopes.REQUEST);
    使用注解来配置作用域是更合适的,由于这样能够使Module对象在不类型中复用。

    Guice有一种特殊的语法来定义须要马上创建的单例对象(Eager Singletons):bind(TransactionLog.class).to(InMemoryTransactionLog.class).asEagerSingleton();
    Eager Singletons对象保证终端使用者获得始终如一的体验。Lazy singletons则更适用于edit-compile-run开发周期。能够通过Stage枚举来选择使用哪一种策略。


      PRODUCTION DEVELOPMENT
    .asEagerSingleton() eager eager
    .in(Singleton.class) eager lazy
    .in(Scopes.SINGLETON) eager lazy
    @Singleton eager* lazy
    *号表示仅仅有已知类型才会马上创建单例对象。所谓已经类型为在Module中使用的类加上这些类的传递性依赖。

    怎样选择作用域:
    假设一个对象是用状态的,它的状态就非常明显了。每一个应用使用则是@Singleton,每一个请求使用则是@RequestScoped。

    假设一
    个对象是无状态的而且创建的代价非常小。就没有必要配置作用域了。Guice每次都创建一个新的对象。


    单例模式在Java应用中非常流行,但这样不能提供多个对象特别是在使用了依赖注入之后。尽管单例模式降低了对象的创建、使垃圾回收推后。但单例对象的初始化须要进行同步。

    单例对象最适用于:
    a.有状态对象,假设配置对象或者计数器
    b.要花非常大的代价去创建或者查找
    c.捆绑了资源的对象。比如数据库连接池


    当一个类加上了@Singleton或者@SessionScoped注解时。它必须是线程安全的。并且被注入到这个类中的类也必须是安全的,应该限制须要进行并发控制状态以最大限度地降低可变性。

    @RequestScoped对象没有必须是线程安全的,所以一个常见的错误是一个@Singleton或@SessionScoped对象依赖了一个@RequestScoped对象。

  • 相关阅读:
    Golang的select多路复用以及channel使用实践
    golang-goroutine和channel
    golang类型转换小总结
    golang之终端操作,文件操作
    golang之结构体和方法
    golang基础之三-字符串,时间,流程控制,函数
    Linux Keepliaved安装
    Git打标签、还原到具体标签版本代码
    Git复制已有分支到新分支开发
    记一次内存分析
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7351609.html
Copyright © 2020-2023  润新知