簡體   English   中英

在春季啟動時注入Bean

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM