問題描述
在 Spring Boot 應用程序中實現工作進程 (Implementing worker processes in a Spring Boot application)
簡介
我目前正在單個網絡測功機上通過 Heroku 運行 Spring‑Boot 應用程序。由於大量密集的後台任務(從 3rd 方 API 獲取資源、發送郵件等),我想將所有這些“繁重的工作”轉移到 在第二個工人測功機/進程上。但是,在將應用程序組件(例如@Repositories)正確地暴露給第二個工作進程時,我面臨著一些困難。
到目前為止我所做的嘗試
我創建了第二個主類 (BackgroundWorker
),我在 Procfile 中將其指定為工作進程。然後調用以下類來初始化後台任務。
<code>@Service
@EnableMongoRepositories("com.a.viz.db")
@ComponentScan("com.a.viz.db")
@EntityScan("com.a.viz.model")
public class TaskHandler {
@Autowired
UProductRepository productRepository;public void initScheduler() { Runnable fetchProducts = () ‑> { Scheduler.fetchProducts(productRepository); }; }
}
</code></pre>雖然主類看起來像這樣:
public class BackgroundWorker {
static Logger logger = LoggerFactory.getLogger(BackgroundWorker.class);public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.scan("com.a.viz.workers"); context.refresh(); TaskHandler handler = context.getBean(TaskHandler.class); handler.initScheduler(); }
}
</code></pre>在運行上面的代碼片段時,我在
UProductRepository 的具體實現中註入了 bean
,稱為MongoTemplate
的不滿意依賴錯誤UProductRepositoryImpl
。public class UProductRepositoryImpl implements UProductRepositoryCustom {
private final MongoTemplate mongoTemplate;@Autowired public UProductRepositoryImpl(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; }
}
</code></pre>
org.springframework.beans.factory.NoSuchBeanDefinitionException:沒有 'org.springframework.data.mongodb 類型的合格 bean。 core.MongoTemplate'
如何將
MongoTemplate
暴露給第二個工作進程?此外,什麼是處理這種事情的好方法?我應該嘗試組織我的組件,以便只有相關的組件暴露給工作進程嗎?感謝您的關注!
參考解法
方法 1:
Solution
Since the worker process must also be a Spring application (in order to allow for injecting repositories and such), its application context must be initialized as such. The web parameter is to prevent a proper web server being set up, since that is not necessary.
// Other configs.. @EnableAutoConfiguration public class BackgroundWorker implements ApplicationRunner { @Autowired // Repositories.. public static void main(String[] args) { new SpringApplicationBuilder(BackgroundWorker.class) .web(WebApplicationType.NONE) .run(args); }
參考文件