2.DispatcherServletInitializer
... protected Class<?>[] getRootConfigClasses(){ return new Class<?>[] { RabbitServerConfiguration.class}; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { RabbitClientConfiguration.class, MvcConfig.class }; } ...3.RabbitServerConfiguration
@Configuration @ComponentScan(basePackages={"org.springframework.amqp.rabbit.stocks.server.*"}) public class RabbitServerConfiguration extends AbstractStockAppRabbitConfiguration { /** * The server's template will by default send to the topic exchange named * {@link AbstractStockAppRabbitConfiguration#MARKET_DATA_EXCHANGE_NAME}. */ public void configureRabbitTemplate(RabbitTemplate rabbitTemplate) { rabbitTemplate.setExchange(MARKET_DATA_EXCHANGE_NAME); } /** * We don't need to define any binding for the stock request queue, since it's relying * on the default (no-name) direct exchange to which every queue is implicitly bound. */ @Bean public Queue stockRequestQueue() { return new Queue(STOCK_REQUEST_ROUTING_KEY); } /** * 主要是注册一个Scheduler */ @Bean public ScheduledAnnotationBeanPostProcessor scheduledAnnotationBeanPostProcessor(){ return new ScheduledAnnotationBeanPostProcessor(); } /** * 这个监听是用于处理客户端发过来的请求. * @param serverHandler * @return */ @Bean public SimpleMessageListenerContainer messageListenerContainer(ServerHandler serverHandler) { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory()); container.setMessageListener(new MessageListenerAdapter(serverHandler,jsonMessageConverter())); container.setQueues(stockRequestQueue()); return container; } }4.RabbitClientConfiguration
@Configuration @ComponentScan(basePackages={"org.springframework.amqp.rabbit.stocks.client.*"}) public class RabbitClientConfiguration extends AbstractStockAppRabbitConfiguration { private String marketDataRoutingKey="app.stock.quotes.#"; @Override public void configureRabbitTemplate(RabbitTemplate rabbitTemplate) { rabbitTemplate.setRoutingKey(STOCK_REQUEST_ROUTING_KEY); } @Bean public Queue marketDataQueue() { return new AnonymousQueue(); } /** * Binds to the market data exchange. Interested in any stock quotes. */ @Bean public Binding marketDataBinding() { return BindingBuilder.bind(marketDataQueue()).to(marketDataExchange()).with(marketDataRoutingKey); } @Bean public MessageListenerAdapter messageListenerAdapter(ClientHandler clientHandler) { return new MessageListenerAdapter(clientHandler, jsonMessageConverter()); } @Bean public SimpleMessageListenerContainer messageListenerContainer(MessageListenerAdapter messageListenerAdapter) { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory()); container.setQueues(marketDataQueue(),traderJoeQueue()); container.setMessageListener(messageListenerAdapter); container.setAcknowledgeMode(AcknowledgeMode.AUTO); return container; } @Bean public Queue traderJoeQueue() { return new AnonymousQueue(); } }
5.ClientHandler
@Component public class ClientHandler { private static Log logger = LogFactory.getLog(ClientHandler.class); private long timeout = 30000; // 30 seconds of data private ConcurrentMap<String, TradeResponse> responses = new ConcurrentHashMap<String, TradeResponse>(); private Queue<Quote> quotes = new PriorityBlockingQueue<Quote>(100, new Comparator<Quote>(){ public int compare(Quote o1, Quote o2) { return new Long(o1.getTimestamp() - o2.getTimestamp()).intValue(); } }); public ConcurrentMap<String, TradeResponse> getResponses() { return responses; } public Queue<Quote> getQuotes() { return quotes; } public void handleMessage(TradeResponse response) { logger.info("Client received: " + response); String key = response.getRequestId(); responses.putIfAbsent(key, response); Collection<TradeResponse> queue = new ArrayList<TradeResponse>(responses.values()); long timestamp = System.currentTimeMillis() - timeout; for (Iterator<TradeResponse> iterator = queue.iterator(); iterator.hasNext();) { TradeResponse tradeResponse = iterator.next(); if (tradeResponse.getTimestamp() < timestamp) { responses.remove(tradeResponse.getRequestId()); } } } public void handleMessage(Quote message) { logger.info("Client received: " + message); long timestamp = System.currentTimeMillis() - timeout; for (Iterator<Quote> iterator = quotes.iterator(); iterator.hasNext();) { Quote quote = iterator.next(); if (quote.getTimestamp() < timestamp) { iterator.remove(); } } quotes.add(message); } /* @Autowired private StockController stockController; public void handleMessage(Quote quote) { Stock stock = quote.getStock(); logger.info("Received market data. Ticker = " + stock.getTicker() + ", Price = " + quote.getPrice()); stockController.displayQuote(quote); } public void handleMessage(TradeResponse tradeResponse) { logger.info("Received trade repsonse. [" + tradeResponse + "]"); stockController.updateTrade(tradeResponse); } */ }