[英]Injecting a bean at startup in Spring
我有一個RunBackgroundServices類,它在啟動時運行一些后台服務。 我需要一個新的對象BackgroundServices。 所以我正在使用WebApplicationContext來獲取bean。 但這不起作用。
RunBackgroundServices.java
@WebListener
public class RunBackgroundServices implements ServletContextListener {
private ExecutorService executor;
public void contextInitialized(ServletContextEvent event) {
final WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
BackgroundServices backgroundServices = springContext.getBean(BackgroundServices.class);
executor = Executors.newSingleThreadExecutor();
executor.submit(backgroundServices); // Task should implement Runnable.
}
public void contextDestroyed(ServletContextEvent event) {
executor.shutdown();
}
}
BackgroundServices.java
@Service
public class BackgroundServices extends Thread {
@Autowired
ServerListener serverListener;
@Autowired
ClientListener clientListener;
private static final Logger logger = LoggerFactory
.getLogger(BackgroundServices.class);
public void run() {
logger.debug("BackgroundServices :: run");
try {
serverListener.start();
} catch (InterruptedException e) {
logger.error(e.getStackTrace().toString());
}
try {
clientListener.start();
} catch (InterruptedException e) {
logger.error(e.getStackTrace().toString());
}
}
}
我收到以下錯誤-
Exception sending context initialized event to listener instance of class com.emc.hl7.common.RunBackgroundServices
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emc.hl7.common.BackgroundServices] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:295)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1125)
at com.emc.hl7.common.RunBackgroundServices.contextInitialized(RunBackgroundServices.java:20)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4961)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5455)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:634)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:671)
at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1840)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
有一種使用Spring執行引導操作的簡便方法。 您所要做的就是擁有實現ApplicationListener<ContextRefreshedEvent>
Spring bean。
您的代碼如下所示:
@Component
public class ContextStartupListener implements ApplicationListener<ContextRefreshedEvent> {
private final BackgroundServices backgroundServices;
private ExecutorService executor;
@Autowired
public ContextStartupListener(BackgroundServices backgroundServices) {
this.backgroundServices= backgroundServices;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if(!isRootApplicationContext(event)) {
return;
}
executor = Executors.newSingleThreadExecutor();
executor.submit(backgroundServices);
}
private boolean isRootApplicationContext(ContextRefreshedEvent event) {
return null == event.getApplicationContext().getParent();
}
}
注意isRootApplicationContext
的使用。 如果您有多個應用程序上下文並且不想在每個應用程序上下文上運行引導操作,則需要它。
使用以上代碼,您將使用Spring的事件而不是Servlet容器的事件進行引導。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.