在web服务器启动时获得spring容器

      我们常常会遇到这种问题:项目中需要在开机时启动某些具有特定功能的线程用来收集数据等,而且需要进行必要的数据库操作,现在框架的集成使得我们不能随意的去创建数据库的连接然后书写我们的数据库方法,所以需要在这个开机的线程中获得spring容器以便获得自己需要的服务层对象。从以上问题的阐述我们可以找到两个要点:1是开机启动,2是在开机启动的线程获得spring容器,ok下面就是冲着这两个要点寻找突破点。

  开机启动的东西对我们来说解决的方法比较简单,就是在web.xml文件下配置一个自定义监听器就可以。这里我们应当注意,这个监听器应该写在spring监听器的下面

 <listener>                                                 
  <listener-class>
  com.hsc.action.StartUpCardReaderListener
  </listener-class>
</listener>


我们可以将它放在web.xml的末尾。接下来我们要顺势在这个监听器里获得spring容器,其实很简单,先给出代码如下

package com.hsc.action;

import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.concurrent.ForkJoinPool;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.hsc.service.IPersonActyPathService;
import com.hsc.service.IReaderService;
import com.hsc.util.AlwaysReceiveDataFromRfid;
import com.hsc.util.ReaderService;
/**
 * 
 * @author ttt
 *
 */
public class StartUpCardReaderListener implements  ServletContextListener,ApplicationContextAware{
    private IPersonActyPathService personActyPathService;
     private IReaderService iReaderService;
    private static ApplicationContext context; 
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) 
    {
        
    }
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) 
    {
        try {
             ReaderService.init();
             personActyPathService = (IPersonActyPathService) context.getBean("personActyPathService"); //即可取到bean 
             iReaderService=(IReaderService) context.getBean("iReaderService");
             //使用ForkJoinPool 实现线程的并发执行
             ForkJoinPool pool=new ForkJoinPool();
             int corenum=Runtime.getRuntime().availableProcessors();
             for(int i=0;i<corenum;i++){
                 pool.invoke(new AlwaysReceiveDataFromRfid(personActyPathService, iReaderService));
             }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
         context = applicationContext;
        
    }

}

我们可以看到除了实现监听器的接口再实现一个ApplicationContextAware的接口就好了,这样spring容器会被装填入这个类里,我们直接使用get方法获得然后就可以获得你想要的各种bean了,当然这里还要注意一点就是

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
  <import resource="spring/application-hibernate.xml"/>
<!--  <import resource="spring/application-stuBean.xml"/>-->
  <import resource="spring/application-bean.xml"/>
  <bean id="SpringConfigTool" class="com.hsc.action.StartUpCardReaderListener"></bean>
</beans>

spring的配置文件中要把这个监听器类的bean给写上,这样才能告知spring把容器注入到这个实现了
ApplicationContextAware接口的类里。

原文地址:https://www.cnblogs.com/wq123/p/3445574.html