我试图找到一种在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());
答案 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
>>>>>>>>>>>>>>