美文网首页
4.Guice实战案例服务

4.Guice实战案例服务

作者: 洛神灬殇 | 来源:发表于2022-04-07 12:40 被阅读0次

    public static void main(String[] args) {

    Injector injector = Guice.createInjector(new BindModule());
    
    DogEgg dogEgg = injector.getInstance(DogEgg.class);
    
    System.out.println(dogEgg.service);
    

    }

    interface Service {}

    public static class DefaultService implements Service {}

    public static class DogEgg {

    // 告诉Guice,这里要注入东西,具体的注入规则从Module里找吧
    
    @Inject
    
    public Service service;
    

    }

    public static class BindModule implements Module {

    @Override
    
    public void configure(Binder binder) {
    
        // 在注入的时候,遇到Service接口类型,全部注入成DefaultService实例
    
        binder.bind(Service.class).to(DefaultService.class);
    
    }
    

    }

    @BindingAnnotation

    @Retention(RetentionPolicy.RUNTIME)

    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})

    public @interface DefaultAnnotation{}

    public static void main(String[] args) {

    Injector injector = Guice.createInjector(new BindModule());
    
    DogEgg dogEgg = injector.getInstance(DogEgg.class);
    
    System.out.println(dogEgg.service);
    
    System.out.println(dogEgg.service2);
    

    }

    interface Service {}

    public static class DefaultService implements Service {}

    public static class DefaultService2 implements Service {}

    public static class DogEgg {

    @Inject
    
    @DefaultAnnotation
    
    // 使用自定义注解标识该字段需要DefaultService实例
    
    public Service service;
    
    @Inject // 没有自定义注解,那就注入DefaultService2实例
    
    public Service service2;
    

    }

    public static class BindModule implements Module {

    @Override
    
    public void configure(Binder binder) {
    
        binder.bind(Service.class).annotatedWith(DefaultAnnotation.class).to(DefaultService.class).
    
         in(Scopes.SINGLETON);
    
        binder.bind(Service.class).to(DefaultService2.class);
    
    }
    

    }

    public static void main(String[] args) {

    Injector injector = Guice.createInjector(new BindModule());
    
    DogEgg dogEgg = injector.getInstance(DogEgg.class);
    
    System.out.println(dogEgg.service);
    
    System.out.println(dogEgg.service2);
    
    System.out.println(dogEgg.service3);
    

    }

    interface Service {}

    public static class DefaultService implements Service {}

    public static class DefaultService2 implements Service {}

    public static class DogEgg {

    @Inject
    
    @Named("service1")
    
    // 注意这里的@Named注解
    
    public Service service;
    
    @Inject
    
    @Named("service2") // 注意这里的@Named注解
    
    public Service service2;
    
    @Inject
    
    public Service service3; // 注意这里的没有@Named注解!!!
    

    }

    public static class BindModule implements Module {

    @Override
    
    public void configure(Binder binder) {
    
        // 被@Named("service1")修饰的,给注入DefaultService实例
    
        binder.bind(Service.class).annotatedWith(Names.named("service1"))
    
                .to(DefaultService.class);
    
        // 被@Named("service2")修饰的,给注入DefaultService2实例
    
        binder.bind(Service.class).annotatedWith(Names.named("service2"))
    
                .to(DefaultService2.class);
    
        // 默认给注入DefaultService实例
    
        binder.bind(Service.class).to(DefaultService.class);
    
    }
    

    }

    DefaultService@fad74ee

    DefaultService2@1a1d6a08

    DefaultService@37d31475 // 和第一行的DefaultService实例不是一个?!

       人家Spring可以配置单例还是原型,Guice也可以,在bind的时候指定一下就行,像上面那样不指定任何Scope的时候,每次注入时都会创建新实例!
    

    public static class DogEgg {

    @Inject
    
    @Named("service1")
    
    public Service service;
    
    @Inject
    
    @Named("service1")
    
    public Service service5;
    
    @Inject
    
    @Named("service2")
    
    public Service service2;
    
    @Inject
    
    public Service service3;
    
    @Inject
    
    public Service service4;
    

    }

    public static class BindModule implements Module {

    @Override
    
    public void configure(Binder binder) {
    
        binder.bind(Service.class).annotatedWith(Names.named("service1"))
    
                .to(DefaultService.class).in(Scopes.SINGLETON); // 这里指定了Scope
    
        binder.bind(Service.class).annotatedWith(Names.named("service2"))
    
                .to(DefaultService2.class);
    
        binder.bind(Service.class).to(DefaultService.class).in(Scopes.SINGLETON); // 这里也指定了Scope
    
    }
    

    }

    输出次序为service1、service5、service2、service3、service4如下:
    
    DefaultService@ed9d034
    
    DefaultService@ed9d034 // service1和service5是一个对象
    
    DefaultService2@6121c9d6
    
    DefaultService@87f383f
    
    DefaultService@87f383f // service3和service4是一个对象,但是与service1和service2不相同
    

    上面这波输出也告诉我们,Guice的单例是按照binding划分的。

    如果要全局单例,可以使用@Singleton注解,代码如下:

    @Singleton

    // 这个注解告诉Guice,该实现全局单例

    public static class DefaultService implements Service {}

    public static class DefaultService2 implements Service {}

    public static class DogEgg {

    @Inject
    
    @Named("service1")
    
    public Service service;
    
    @Inject
    
    @Named("service1")
    
    public Service service5;
    
    @Inject
    
    @Named("service2")
    
    public Service service2;
    
    @Inject
    
    public Service service3;
    
    @Inject
    
    public Service service4;
    

    }

    public static class BindModule implements Module {

    @Override
    
    public void configure(Binder binder) {
    
        binder.bind(Service.class).annotatedWith(Names.named("service1")).to(DefaultService.class);
    
        // 这里没有再指定Scope
    
        binder.bind(Service.class).annotatedWith(Names.named("service2")).to(DefaultService2.class);
    
        binder.bind(Service.class).to(DefaultService.class);  // 这里没有再指定Scope
    
    }
    

    }

       这里的Singleton到底是懒汉模式还是饿汉模式呢?这个也是可以配置的,默认是懒汉模式,就是延迟加载!!!其实懒汉和饿汉模式在代码跑起来之后,没啥太大差别,毕竟该创建的都创建了。要是想详细理解的话,翻翻文档吧,这个不是特别重要。除了Singleton之外,还有Scope,例如ServletScopes.REQUEST,也去看文档吧,这个也不是特别重要。
    
    除了上面介绍的字段注入,Guice还可以通过构造注入:
    
    public static void main(String[] args) { 
    
        Injector injector = Guice.createInjector(new BindModule());
    
        DogEgg dogEgg = injector.getInstance(DogEgg.class);
    
        System.out.println(dogEgg.service);
    
        System.out.println(dogEgg.service5);
    
        System.out.println(dogEgg.service2);
    
        System.out.println(dogEgg.service3);
    
        System.out.println(dogEgg.service4);
    

    }

    interface Service {}
    

    @Singleton

    public static class DefaultService implements Service {

    private String name;
    
    private TestArg testArg;
    
    public DefaultService(String name, TestArg testArg) { // 构造函数
    
        this.name = name;
    
        this.testArg = testArg;
    
    }
    
    public DefaultService() {} // 无参构造函数
    
    @Override
    
    public String toString() { // 这里专门加了一个hashCode(),用于区分是不是一个对象
    
        return hashCode() +" DefaultService{" +
    
                "name='" + name + '\'' +
    
                ", testArg=" + testArg +
    
                '}';
    
    }
    

    }

    public static class DefaultService2 implements Service {}

    public static class DogEgg {

    @Inject
    
    @Named("service1")
    
    public Service service;
    
    @Inject
    
    @Named("service1")
    
    public Service service5;
    
    @Inject
    
    @Named("service2")
    
    public Service service2;
    
    @Inject
    
    public Service service3;
    
    @Inject
    
    public Service service4;
    

    }

    public static class TestArg {

    }

    public static class BindModule implements Module {

    @Override
    
    public void configure(Binder binder) {
    
        // 碰到@Named("service1")注解修饰的注入,继续走无参构造函数
    
        binder.bind(Service.class).annotatedWith(Names.named("service1")).to(DefaultService.class);
    
        binder.bind(Service.class).annotatedWith(Names.named("service2"))
    
                .to(DefaultService2.class);
    
        // binder.bind(Service.class).to(DefaultService.class);
    
        // 这与下面走构造函数的binding冲突,Guice不知道该走哪个构造方法
    
        try {
    
            binder.bind(Service.class) // 没有@Named("service1")注解修饰的注入,走构造方法
    
                    .toConstructor(DefaultService.class
    
                            .getConstructor(String.class, TestArg.class));
    
        } catch (NoSuchMethodException e) {
    
            e.printStackTrace();
    
        }
    
    }
    

    }

    相关文章

      网友评论

          本文标题:4.Guice实战案例服务

          本文链接:https://www.haomeiwen.com/subject/ucnjsrtx.html