这个行为能够通过scopes进行配置。Scopes同意你复用实例:
应用整个生命周期(@Singleton),会话(@Session),请求(@RequestScoped),Guice还提供为Web应用提供了一种Servlet扩展作用域。而且在Guice还能够自己定义范围。
Guice使用注解来标识作用域,将注解加入到某一类型的实现类上:
@Singleton
public class InMemoryTransactionLog implements TransactionLog {
/* everything here should be threadsafe! */
}
bind(TransactionLog.class).to(InMemoryTransactionLog.class).in(Singleton.class);
@Provides @Singleton
TransactionLog provideTransactionLog() {
...
}bind(Bar.class).to(Applebees.class).in(Singleton.class); bind(Grill.class).to(Applebees.class).in(Singleton.class);
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对象在不类型中复用。
| PRODUCTION | DEVELOPMENT | |
| .asEagerSingleton() | eager | eager |
| .in(Singleton.class) | eager | lazy |
| .in(Scopes.SINGLETON) | eager | lazy |
| @Singleton | eager* | lazy |
怎样选择作用域:
假设一个对象是用状态的,它的状态就非常明显了。每一个应用使用则是@Singleton,每一个请求使用则是@RequestScoped。
假设一
个对象是无状态的而且创建的代价非常小。就没有必要配置作用域了。Guice每次都创建一个新的对象。
单例模式在Java应用中非常流行,但这样不能提供多个对象特别是在使用了依赖注入之后。尽管单例模式降低了对象的创建、使垃圾回收推后。但单例对象的初始化须要进行同步。
单例对象最适用于:
a.有状态对象,假设配置对象或者计数器
b.要花非常大的代价去创建或者查找
c.捆绑了资源的对象。比如数据库连接池
当一个类加上了@Singleton或者@SessionScoped注解时。它必须是线程安全的。并且被注入到这个类中的类也必须是安全的,应该限制须要进行并发控制状态以最大限度地降低可变性。
@RequestScoped对象没有必须是线程安全的,所以一个常见的错误是一个@Singleton或@SessionScoped对象依赖了一个@RequestScoped对象。
原文:http://www.cnblogs.com/claireyuancy/p/7351609.html