问答详情
源自:4-2 绑定(下)

Provider绑定

还是不明白Provider绑定有什么用,感觉就类似于一工厂么,需要的时候创建一个bean,但是如果在configure()方法里面注入的话缺又相当于一个单例bean(前提开发人员不去new),有点搞不懂...,请问它到底用在什么地方?另外对于非接口类型的依赖无需代码绑定,Guice会自动创建,那么就没必要使用Provider啊,需要的时候Guice总会给我一个

提问者:长袜子皮皮93 2019-10-26 23:12

个回答

  • 慕雪4495629
    2020-12-22 16:18:17

    稍微改了下代码, 这种情况下, 似乎只有使用 Provide 了

    trait Db
    
    class MemoryDb extends Db
    
    @Singleton
    class DatabaseActor @Inject() (@Name("MemoryDb") db: Db) extend Actor {    
        // ......
    }  
    
    // 这里还是使用的 bind 来绑定注入
    class DbClient @Inject() (@Name("DbActor") actorRef: ActorRef)  
    
    // ActorSystem 可以由启动类中来实例化
    class MyModule(system: ActorSystem) extends AbstractModule with ScalaModule {         bind[Db].annotatedWith(Names.named("MemoryDb")).to[MemoryDb]
        
        @Provides
        @Named("DbActor")
        // 这里的参数 Db 只有靠 Provide 的绑定传递了.
        def dbActorRef(db: Db): ActorRef = {
           system.actorOf(Props.create(classOf[DbActor], db))
        }
    }


  • 慕雪4495629
    2020-12-22 16:04:19

    又想了想, 如果这么写, 好像确实可以不用 Provide (但Provide 提供的延迟加载的能力, bind 无法实现)

    @Singleton
    class DatabaseActor extend Actor {
        // ......
    } 
    
    // 这里还是使用的 bind 来绑定注入
    class DbClient @Inject() (@Name("Database") actorRef: ActorRef) 
    
    // ActorSystem 可以由启动类中来实例化
    class MyModule(system: ActorSystem) extends AbstractModule with ScalaModule {     
        bind[ActorRef].annotatedWith(Names.named("Database"))
            .toInstance(system.actorRef(Props.create(classOf[DatabaseActor])))
    }


  • 慕雪4495629
    2020-12-22 15:45:57

    如果一个类的构造方法不是由你控制的, 比如 Akka 里的 ActorRef 的实例方法, 源码对外只提供了 ActorSystem.actorOf()这种方式, 这个时候就需要使用 Provider 来告诉 Guice ActorRef 的实例如何来构造

    这里的 actorRef 的实例化方式只能由 ActorSystem.actorOf() 实现

    class DatabaseActor extend Actor {
        // ......
    }
    
    // 这里 Guice 会使用 provide 中提供的 DatabaseActor 的构造方法来注入
    class DbClient @Inject() (@Name("Database") actorRef: ActorRef)
    
    class MyModule extends AbstractModule with ScalaModule {
    
        bind[ActorSystem].toInstance(ActorSystem("DbSystem"))
    
        @Provides
        @Singleton
        @Name("Database")
        def generateDbActor(system: ActorSystem): ActorRef {
            system.actorOf(Props.create(classOf[DatabaseActor]))
        }
    }


  • weibo_慕神4450614
    2020-01-16 16:42:42

    很好的问题 同问