第 7 章 作用域(scope)

默认下就是单例(singleton)与原型(prototype)的区别,自定义scope的情况还没搞明白。

7.1. 使用Module配置

现在要将ServiceImpl.class制作成一个单例(singleton),不管是哪个类需要注入Service,我们都返回唯一的实例,为了达到这种效果,我们在Module中进行配置。

import com.google.inject.*;

public class Main {
    @Inject
    private Service service;

    public static void main(String[] args) {
        Main main = Guice.createInjector(new Module() {
            public void configure(Binder binder) {
                binder.bind(Service.class).to(ServiceImpl.class)
                                        .in(Scopes.SINGLETON);
            }
        }).getInstance(Main.class);

        main.service.hello();
    }
}
        

bind(),to(),最后是in(Scopes.SINGLETON),将Service.class放到SINGLETON这个作用域中。guice会保证每个Injector里都只有一个ServiceImpl.class实例。

以后我们获得的Service.class都将是同一个实例。

例子:07-01。

7.2. 使用注解

既然我们可以把依赖关系写成@ImplementedBy的形式,那么单例也可以直接写成注解。

向ServiceImpl.java中添加@Singleton注解。

import com.google.inject.*;

@Singleton
public class ServiceImpl implements Service{
    public void hello() {
        System.out.println("hello");
    }
}
        

这样Main.java就不再需要写Module了。

import com.google.inject.*;

public class Main {
    @Inject
    private Service service;

    public static void main(String[] args) {
        Main main = Guice.createInjector().getInstance(Main.class);

        main.service.hello();
    }
}
        

例子:07-02。

7.3. 立即初始化单例

默认情况下,单例会在第一次被调用的时候创建,我们也可以在createInjector()就对它进行初始化。

import com.google.inject.*;

public class Main {
    @Inject
    private Service service;

    public static void main(String[] args) {
        Main main = Guice.createInjector(new Module() {
            public void configure(Binder binder) {
                binder.bind(Service.class).to(ServiceImpl.class).asEagerSingleton();
            }
        }).getInstance(Main.class);

        main.service.hello();
    }
}
        

这里我们使用asEagerSingleton()代替in(Scopes.SINGLETON),这样ServiceImpl会做为单例在createInjector()执行的同时立即加载,供以后使用。

例子:07-03。