春季引导。如何利用原型范围?

时间:2019-04-09 09:15:34

标签: java spring spring-boot runnable

我试图找到一种在Spring启动中创建优美的Runnable bean的方法。该应用程序的重点是提供一项服务,该服务将接收一些数据并启动受监视的外部过程。

在先前的尝试中,我只是形成一个常规new MyRunnable()并将其传递给执行服务。现在,我正在考虑如何使用Spring环境并使用@Scope("prototype")

我确实找到了使用ApplicationContext.getBean(...)和更好的Why is Spring's ApplicationContext.getBean considered bad?方法的示例,但是我仍然无法正确地理解如何根据一项服务来实际调用new MyRunnable(),遵循以下简单思想:

class MyService {
  public void triggerNewExternalTask() {
       ....
       executionService.run(new MyRunnable());

2 个答案:

答案 0 :(得分:5)

我相信您在这里走错了路。

Spring依赖项注入非常棒,但这并不意味着您永远不会在正确编写的Spring Boot应用程序中找到对new的调用。

在这种情况下,调用new是正确的做法。池中的每个Executor在启动时都应拥有自己的Runnable / Callable实例。

这对于任何方法范围变量都是如此:最好在方法范围内实例化它,并在退出方法时让垃圾回收器将其清除。在这种情况下,没有理由让Spring负责bean的生命周期。

当您尝试共享Runnable实例时,您走得太远了,尤其是当它们具有状态时。

答案 1 :(得分:0)

即使问题已关闭,也偶然发现了另一个解决方案-@Lookup,它可以满足以下任务: 实体:

@Component
@Scope("prototype")
public class Proto {
    private static int counter;
    public Proto() {
        System.out.println("count: "+counter++);
    }
}

服务:

@Service
public class ProtoService {
    @Lookup
    public Proto getProto() {
        return null;
    }
}

和测试:

@Service
public class LookupWorks {
    @Autowired
    private ProtoService serv;

    @PostConstruct
    private void test() {
        System.out.println(">>>>>>>>>>>>>>");
        serv.getProto();
        serv.getProto();
        serv.getProto();
        serv.getProto();
        serv.getProto();
        System.out.println(">>>>>>>>>>>>>>");
    }


}

输出:

>>>>>>>>>>>>>>
count: 0
count: 1
count: 2
count: 3
count: 4
>>>>>>>>>>>>>>