在Spring中重构这个的最佳方法是什么?

7
private final ExecutorService executorParsers = Executors.newFixedThreadPool(10);

public void parse(List<MyObjInt> objs) {
   //... bunch of elided stuff ....

   CompletionService<AsupParseObj> parserService = new ExecutorCompletionService<AsupParseObj>(executorParsers);

   for (final AsupStoreObj obj : objs) {
      parserService.submit(new ParseThread(obj));
   }
}

我想对“ParseThread”进行DI,但肯定有比将getBean调用封装在原型作用域的Bean里更好的方法,因为我是Spring的新手,所以我想问问……


使用Spring DI,你需要让你的对象更像一个POJO。所以,鉴于这一点,我可以想象出几种你可以在代码中采取的方式。你能提供一个更大的片段和一些额外的上下文来解释你想要做什么吗? - Chris J
1
看起来你的 ParseThread 除了 AsupStoreObject 没有其他依赖...在这种情况下...你想让 Spring 帮忙做什么? - Dapeng
1
我的意图是能够注入ParseThread可调用对象,这样我就可以更轻松地切换/模拟它们,而不是像这段代码一样被绑定到ParseThread的特定实现。 - user1085751
2个回答

7
这是使用lookup-method的完整配置(参见3.4.6.1 查找方法注入):
<bean id="executorParsers" class="java.util.concurrent.Executors" 
        factory-method="newFixedThreadPool" 
        destroy-method="shutdownNow">
    <constructor-arg value="10"/>
</bean>

<bean id="parserService" class="java.util.concurrent.CompletionService">
    <constructor-arg ref="executorParsers"/>
</bean>

<bean id="foo" class="Foo">
    <lookup-method name="createThread" bean="parseThread"/>
</bean>

<bean id="parseThread" class="ParseThread" scope="prototype" lazy-init="true"/>

而这是Java代码:

abstract class Foo {

    @Autowired
    CompletionService parserService;

    protected abstract ParseThread createThread();

    public void parse(List<MyObjInt> objs) {
        for (final AsupStoreObj obj : objs) {
            ParseThread t = createThread();
            t.setObject(obj);
            parserService.submit(t);
        }
    }
}

很遗憾,您无法向lookup-method传递任何参数(请参见SPR-7431和我的文章使用lookup-method按需创建Spring原型bean),因此需要人工进行setObject()

如果您不喜欢abstract方法/类,则可以将lookup方法设置为非抽象的空操作方法,或者(更好的办法)默认实现可抛出异常。Spring将在运行时覆盖实现,有效地为您调用getBean()

提示:我还将Executor/CompletionService翻译成了Spring管理的bean。请注意,Spring支持这些功能:任务执行和调度


对于Spring版本3.0.5,我不得不将java.util.concurrent.CompletionService更改为java.util.concurrent.ExecutorCompletionService,因为CompletionService是一个接口,所以由于歧义而无法实例化。 - Alex Fedulov

0

嗯,我不确定你认为Spring会在这里给你带来什么,但我会注入某种工厂,它会输出Runnable/Callable

private final ExecutorService executorParsers = Executors.newFixedThreadPool(10);

@Autowired
private CallableFactory myCallableFactory = new MyCallableFactory(); //create this factory

public void parse(List<MyObjInt> objs) {
   //... bunch of elided stuff ....

   CompletionService<AsupParseObj> parserService = new ExecutorCompletionService<AsupParseObj>(executorParsers);

   for (final AsupStoreObj obj : objs) {
      parserService.submit(myCallableFactory.createCallable(obj));
   }
}

你也可以使用Spring来注入ExecutorService


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接