简体   繁体   English

Guice自定义范围和Spring托管bean

[英]Guice Custom Scopes and Spring managed beans

(x-posted to guice mailing list) (x发布到guice邮件列表)

I'm trialling Guice on a new library that will live in an existing application. 我正在新库中试用Guice,该库将存在于现有应用程序中。 All our apps right now are spring apps and we have some common code that is tied to spring, mainly to do with the thread model we tend to use. 现在,我们所有的应用程序都是spring应用程序,并且我们有一些与spring相关的通用代码,主要与我们倾向于使用的线程模型有关。 It basically gives us (what could be seen as) a logical thread. 它基本上给了我们(可以被视为)逻辑线程。

So we can throw jobs at it and it ensures that jobs with a given key always end up on the same pipe in the order that they were submitted. 因此,我们可以向其投掷作业,并确保具有给定密钥的作业始终以提交的顺序结束在同一管道上。 Typically this is a single thread for the life of the application but if bad things happen then the worker thread (that backs the pipe) is thrown away, the pipe deactivated, a new worker created and the pipe reactivated on that worker. 通常,这是应用程序生命周期中的单个线程,但是如果发生不良情况,则会丢弃工作线程(支持管道),取消激活管道,创建新的工作线程并在该工作线程上重新激活管道。 All the wiring here is provided by spring. 此处的所有接线均由弹簧提供。

My new lib needs to use this for the thread model & I plan on using guice for the logic & domain side of things, ie constructing the work that goes on the pipeline & and the logic that it represents. 我的新库需要将其用于线程模型,我计划将guice用于事物的逻辑和域方面,即构造流水线及其表示的逻辑中的工作。 This seems quite straightforward to me except for one thing that seems quite gnarly, namely that I want to inject certain things with "pipe" (aka logical thread) scope. 对我来说,这似乎很简单,除了一件看起来很粗糙的东西,即我想用“管道”(又名逻辑线程)范围注入某些东西。 I've read the custom scopes (and SimpleScope implementation) wiki page but some things are not clear to me and clarification would be much appreciated... 我已经阅读了自定义范围(和SimpleScope实现)维基页面,但是有些事情对我来说并不明确,请多多指教...

  1. pipes survive for the life of the JVM therefore it seems that I need to enter a scope but never exit, any downsides to this? 管道在JVM的整个生命周期中都可以生存,因此,似乎我需要进入一个作用域,但永不退出,这有什么缺点?
  2. what options do I have for triggering scope entry in a spring managed bean? 在Spring托管的bean中,我有什么选项来触发作用域条目? is it just a case of creating the spring context and then using the SpringIntegration to suck in the spring beans into a guice context? 这是创建spring上下文,然后使用SpringIntegration将spring bean引入guice上下文的一种情况吗?
  3. does this sound really flaky and I should just wrap it with a singleton keyed by my pipe id instead? 这听起来真的很片状,我应该用我的管道ID锁定的单例包装它,而不是呢?

Cheers Matt 欢呼马特

I've implemented something which works but involves some slightly ugly setup... still interested in any improvements on this & there may be a bit too much code to post really so just put some snippets in that hopefully illuminates 我已经实现了一些可行的方法,但涉及到一些有点丑陋的设置...仍然对此有所改进,并且可能会发布太多代码,因此只需在其中添加一些摘要即可

it's aa variation on the SimpleScope example which involves; 这是涉及到的SimpleScope示例的一个变体;

  • bringing up the spring ctx 调出Spring ctx
  • grabbing a specific bean out of it (that is a registry of pipeline keys) 从中获取特定的bean(这是管道键的注册表)
  • passing that to the Guice module along with the beanfactory 将其与beanfactory一起传递给Guice模块
  • giving that registry to the Scope impl so the scope is entered when the pipe is activated (which happens later when certain spring beans are init'ed) 将注册表赋予Scope impl,以便在激活管道时输入范围(稍后在初始化某些Spring bean时发生)

It seems I have to grab the specific bean rather than access it through a Named after doing a bindAll on the beanfactory as the Scope instance is new'ed yourself in the Module, ie 似乎我必须抓住特定的bean,而不是在beanfactory上执行bindAll之后通过Named访问它,因为Scope实例是在Module中自己创建的,即

    PipeScope<SecurityId> pipeScope = new PipeScope<SecurityId>();
    pipeScope.setPipeIdRegistry(pipeIdRegistry);
    bindScope(Pipe.class, pipeScope);
    bind(PipeScope.class)
            .annotatedWith(Names.named("pipeScope"))
            .toInstance(pipeScope);
    SpringIntegration.bindAll(binder(), beanFactory);

The fact I have to new it means I need to explicitly provide the registry to the module, can't see a way around this as it's a chicken & egg situation. 我必须重新安装它的事实意味着我需要向模块明确提供注册表,因为这是鸡与蛋的情况,所以看不到解决方法。

The PipeScope basically stores values against the pipe key (actually a List of keys) as opposed to a ThreadLocal so my enter is like PipeScope基本上是针对与ThreadLocal相对的管道键(实际上是键列表)存储值的,所以我的输入就像

public void enter(List<K> scopedKeys) {
    checkState(values.get(scopedKeys) == null, "A scoping block is already in progress");
    values.put(scopedKeys, Maps.<Key<?>, Object>newHashMap());
}

all in all seems to function perfectly well... at least in my quickly knocked up test harness anyway 总而言之,它似乎运行得非常完美……至少在我迅速被淘汰的测试工具中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM