spring 在web 容器启动时,执行FIFO队列初始化方法解析

阿里 阅读:216 2021-03-31 21:33:00 评论:0

解决方案:web容器添加一个Listener类,在容器启动的时候执行Listener的“初始化”方法,在这个初始化方法中执行FIFO队列的初始化工作。

解决方法:spring给出的解决方案——写一个类,实现InitializingBean接口,然后交由spring容器管理。


示例代码:

package com.settlement.initialization; 
 
import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.LinkedBlockingQueue; 
 
import javax.servlet.ServletContext; 
 
import org.springframework.beans.factory.InitializingBean; 
import org.springframework.web.context.ServletContextAware; 
 
public class InitFIFOListener implements InitializingBean, ServletContextAware{ 
	 
	public BlockingQueue<Object> queue = new  LinkedBlockingQueue<Object>(); 
 
	public void setServletContext(ServletContext context) { 
		// TODO Auto-generated method stub 
		 
	} 
 
	public void afterPropertiesSet() throws Exception { 
		// TODO Auto-generated method stub 
		 
	} 
 
	public BlockingQueue<Object> getQueue() { 
		return queue; 
	} 
 
	public void setQueue(BlockingQueue<Object> queue) { 
		this.queue = queue; 
	} 
	 
	 
	 
	 
 
} 

spring-mybatis.xml配置文件信息

   <!--初始化全局(FIFO队列)  --> 
    <bean id="initFIFO" class="com.settlement.initialization.InitFIFOListener"> 
    </bean>

项目全局FIFO队列引用

package com.settlement.controller; 
 
import java.math.BigDecimal; 
import java.util.Queue; 
import java.util.concurrent.BlockingQueue; 
 
import javax.servlet.http.HttpServletRequest; 
 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.ResponseBody; 
 
import com.settlement.commons.base.BaseController; 
import com.settlement.commons.email.SendMailUtil; 
import com.settlement.commons.scan.SpringUtils; 
import com.settlement.initialization.InitFIFOListener; 
import com.settlement.model.AccountWallet; 
import com.taobao.api.internal.util.StringUtils; 
 
/** 
 * 邮箱控制器Controller 
 *  
 * @author zzg 
 * @date 2017-02-10 
 */ 
@Controller 
@RequestMapping(value = "/email") 
public class EmailController extends BaseController { 
	private BlockingQueue<Object> queue = null; 
 
	/** 
	 * 针对业务系统高并发-----采用FIFO队列,进行解决 
	 *  
	 * @return 
	 */ 
	@RequestMapping(value = "/receiveemail.action", method = RequestMethod.POST) 
	@ResponseBody 
	public String receiveEmail(HttpServletRequest request) { 
 
		String result = ""; 
		try { 
			//项目全局FIFO 队列 
			if (queue == null) { 
				InitFIFOListener listener = (InitFIFOListener) SpringUtils 
						.getContext().getBean("initFIFO"); 
				queue = listener.queue; 
			} 
			System.out.println("队列大小:"+queue.size()); 
			String receiveMailAccount = request.getParameter("email") == null ? null 
					: request.getParameter("email").trim(); 
			queue.offer(receiveMailAccount); 
 
		} catch (Exception e) { 
			result = e.getMessage(); 
			return result; 
		} 
 
		return "success"; 
	} 
 
	/** 
	 * 处理FIFO队列,需要发送的邮件信息 
	 *  
	 * @return 
	 */ 
	@RequestMapping(value = "/sendemail.action", method = RequestMethod.POST) 
	@ResponseBody 
	public String sendEmail() { 
 
		String result = ""; 
		boolean isRunning = true; 
		try { 
			//项目全局FIFO 队列 
			if (queue == null) { 
				InitFIFOListener listener = (InitFIFOListener) SpringUtils 
						.getContext().getBean("initFIFO"); 
				queue = listener.queue; 
			} 
			while (isRunning) { 
				System.out.println("队列大小:"+queue.size()); 
				System.out.println("正从队列获取数据..."); 
				String data = (String) queue.poll(); 
				if (null != data) {					 
					System.out.println("正在消费数据:" + data); 
					SendMailUtil.send_163(data); 
				} else { 
					// 超过2s还没数据,认为所有生产线程都已经退出,自动退出消费线程。 
					isRunning = false; 
				} 
			} 
 
		} catch (Exception e) { 
			result = e.getMessage(); 
			return result; 
		} finally { 
			System.out.println("退出消费者线程!"); 
		} 
 
		return "success"; 
	} 
 
} 

到此,问题搞定。


声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

发表评论
搜索
排行榜
KIKK导航

KIKK导航

关注我们