此文是在前文的基础上,将基于XML的方式改为基于Java-config.
一.调整类的位置.
1.项目目录结构如下:
stocks
client
gateway
handler
config
domain
server
gateway
handler
service
stubs
web
其它的做小调整就差不多了.
二.测试.
一.调整类的位置.
1.项目目录结构如下:
stocks
client
gateway
handler
config
domain
server
gateway
handler
service
stubs
web
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);
}
*/
}
其它的做小调整就差不多了.
二.测试.