web应用中非spring控制类调用spring管理的javaBean?

一瓢清风2 2012-12-15 11:48:06
最近一个项目使用listener 触发一个定时器轮询入库,可悲的发现执行类注入的javabean为null;google下来的方法不起作用,就来这里求大神帮忙了。
Timer timer = new Timer(true);
GrddSaveTask task = new GrddSaveTask();//这里由于listener早于servlet初始化,所以task注入参数为空。
timer.schedule(task, 1, 20);
如何在真正使用的时候,因为使用的时候spring已经启动了,给需要注入的Mng初始化。
或者如何子在一个非spring控制的类中获得当前环境中的spring Context。
...全文
291 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
袭烽 2013-01-05
  • 打赏
  • 举报
回复
如果spring的调用方和web容易有关联,因为spring的上下文一般是随web容器启动的,所以获取spring的bean一般可以通过web容器的上下文直接拿到,代码如下: WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); 但是这种方式过渡依赖web容器,如果是单独类想用spring中的bean此方案不可用; 如果调用方也被spring配置管理,那可以用注解,get/set,构造器来获取spring中的其他bean 如果调用方既没有被spring管理,也没有和容器上下文有任何关系,想获取spring中的bean,只能借助BeanFactory工厂了,由工厂来为你创造,好多人就会想到用ClassPathXmlApplicationContext类似方式重新加载一遍spring配置构造一个ApplicationContext上下文或者一个工厂,岂不知这样做就会产生两个spring环境的上下文,另一个就是web端启动了一个spring环境上下文,我们如何只让spring的环境只启动一次呢?答案很简单,代码如下: <bean id="serviceLocator" class="org.androidpn.server.service.ServiceLocator" scope="singleton" /> 在spring的配置文件中配置一个serviceLocator,让web容器启动spring的时候将spring的上下文(也就是BeanFactory)传到我们定义的serviceLocator类中,代码如下:

public class ServiceLocator implements BeanFactoryAware {
    private static BeanFactory beanFactory = null;

    private static ServiceLocator servlocator = null;

    public void setBeanFactory(BeanFactory factory) throws BeansException {
	this.beanFactory = factory;
    }

    public BeanFactory getBeanFactory() {
	return beanFactory;
    }

    public static ServiceLocator getInstance() {
	if (servlocator == null)
	    servlocator = (ServiceLocator) beanFactory.getBean("serviceLocator");
	return servlocator;
    }
    /**
     * 根据提供的bean名称得到相应的服务类
     * 
     * @param servName
     *            bean名称
     */
    public static Object getService(String servName) {
	return beanFactory.getBean(servName);
    }
}
这样在你的工程中任何地方想获取到spring上下文中的bean实例都可以通过ServiceLocator类来获得,堪称两全其美,内圣外王!!
s478853630 2013-01-04
  • 打赏
  • 举报
回复
/**
 * 服务器启动关闭的监听器
 * @version 1.0
 */
public class GlobalListener implements ServletContextListener {
	
	private static final Logger log = LoggerFactory.getLogger(GlobalListener.class);
	private Timer timer = new Timer();

	/**
	 * 关闭服务器
	 */
	public void contextDestroyed(ServletContextEvent event) {
		log.info("关闭服务器");
		timer.cancel();
	}

	/**
	 * 启动服务器
	 */
	public void contextInitialized(ServletContextEvent event) {
		log.info("启动服务器");
		FrameConfig.waterImgPath = "/common_res/images/water.jpg";
		FrameConfig.maxCacheSize = 10000;
		FrameConfig.encoding = "UTF-8";
		timer.schedule(new TaskTimer(), getMillisecond(), Task.daySeconds * 1000l);// 每天执行一次
	}
	
	// 从现在到明天最早时间相差的毫秒数
	private Long getMillisecond() {
		DateUtil util = DateUtil.getBean();
		String beginTime = util.getDetachDate(util.getNowDate(0) + " 00:00:00", 2, Task.daySeconds.intValue());
		return util.getDateDiff(util.getNowDate(1), beginTime) * 1000l;
	}

}


/**
 * 每天最早时间刷新客服回访任务的定时器
 * @version 1.0
 */
public class TaskTimer extends TimerTask {
	
	private static final Logger log = LoggerFactory.getLogger(TaskTimer.class);

	@Override
	public void run() {
		TaskMng mng = (TaskMng) BeanContainer.getBean(TaskMng.class);
		Integer num = mng.renovate();
		log.info("今天最早时间产生了" + num + "个客服回访任务");
		CrmHistory.CRM_HISTORY_MAP = new HashMap<String, List<CrmHistory>>();
	}

}



web.xml


<listener>
		<listener-class>com.xxx.GlobalListener</listener-class>
	</listener>

67,514

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧