我试图找到一种方法在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());
我相信你走错了路。
Spring依赖注入很棒,但这并不意味着你永远不会在正确编写的Spring Boot应用程序中找到对new
的调用。
这是一个调用new
是正确的事情。池中的每个Executor
在启动时都应该得到自己的Runnable
/ Callable
实例。
对于任何方法范围的变量都是如此:更好地在方法范围中实例化它,并在退出方法时让垃圾收集器清理它。在这种情况下,Spring没有理由对bean的生命周期负责。
当你试图分享Runnable
实例时,你走得太远,特别是如果它们有状态。
即使问题已经结束,也会遇到另一个解决方案,即@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
>>>>>>>>>>>>>>