2015-12-03 183 views
1

我正在嘗試使用org.springframework.data.redis.listener.RedisMessageListenerContainer在redis pubsub頻道上偵聽。彈簧數據redis消息偵聽器偵聽消息兩次

我MessageListener類看起來像這樣

@Component 
public class RedisMessageListener { 

    @Autowired 
    private ProcessAdapterImpl processAdapter; 

    private static Logger logger = LoggerFactory.getLogger(RedisMessageListener.class); 

    public void handleMessage(Serializable message, String channel) { 
     logger.debug("handleMessage >>>>> Message received: " + message.toString() + " channel:" + channel); 
     processAdapter.onEventReceived(message.toString()); 
    } 
} 

,並在應用程序上下文

<bean id="tbProperties" 
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="location"> 
     <value>classpath:conf/notifier-local.properties 
     </value> 
    </property> 
</bean> 
<bean id="jedisConnectionFactory" 
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> 
    <property name="hostName" value="${redis.server}" /> 
    <property name="port" value="${redis.port}" /> 
    <property name="usePool" value="true" /> 
</bean> 

<!-- redis template definition --> 
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" 
    p:connection-factory-ref="jedisConnectionFactory" /> 

<bean id="redisPublisher" 
    class="com.vgroup.apps.notifier.event.publisher.RedisPublisherImpl" /> 

<bean id="messageListener" 
    class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter"> 
    <constructor-arg> 
     <bean class="com.vgroup.apps.notifier.event.listener.RedisMessageListener" /> 
    </constructor-arg> 
</bean> 

<bean id="redisContainer" 
    class="org.springframework.data.redis.listener.RedisMessageListenerContainer"> 
    <property name="connectionFactory" ref="jedisConnectionFactory" /> 
    <property name="messageListeners"> 
     <map> 
      <entry key-ref="messageListener"> 
       <bean class="org.springframework.data.redis.listener.ChannelTopic"> 
        <constructor-arg value="${redis.queue}" /> 
       </bean> 
      </entry> 
     </map> 
    </property> 
</bean> 

Redis的發行人看起來像下面

@Component 
public class RedisPublisherImpl implements IRedisPublisher { 

    @Autowired 
    private StringRedisTemplate redisTemplate; 

    @Autowired 
    private ObjectMapper mapper; 

    private static Logger logger = LoggerFactory.getLogger(RedisPublisherImpl.class); 

    public void afterPropertiesSet() throws Exception { 
    } 

    @Override 
    public void publish(Object event) { 
     logger.info("Start executing publish object"); 
     try { 
      String jsonString = mapper.writeValueAsString(event); 
      redisTemplate.convertAndSend("notifications", jsonString); 
     } catch (Exception e) { 
      logger.error(e.getMessage(), e); 
     } 

     logger.info("End executing publish object"); 
    } 
} 

此配置,由於一些奇怪的原因,我即使是由我的p發送消息兩次(有時甚至3-4次) ublisher只有一次

在我的日誌,我可以看到,它是由2個不同的線程rediscontainer

2015-12-03 09:13:12.152 [redisContainer-2] DEBUG c.v.a.n.e.l.RedisMessageListener - handleMessage >>>>> Message received: abc channel:notifications 
2015-12-03 09:13:12.152 [redisContainer-2] DEBUG c.v.a.n.e.l.RedisMessageListener - handleMessage >>>>> Message received: def channel:notifications 
2015-12-03 09:13:12.156 [redisContainer-3] DEBUG c.v.a.n.e.l.RedisMessageListener - handleMessage >>>>> Message received: abc channel:notifications 
2015-12-03 09:13:12.157 [redisContainer-3] DEBUG c.v.a.n.e.l.RedisMessageListener - handleMessage >>>>> Message received: def channel:notifications 

回答

3

檢查聽了消息,如果豆正在創建的兩倍(即認購正在發生兩次)。我有類似的問題,在web.xml中。我有兩個contextListener和DispatchServlet,它們通過訂閱兩次來初始化bean兩次。

+1

謝謝@ JaraviS這真的很有幫助。我有一個在啓動時加載的servlet,因爲我有這一行 ApplicationContext context = new ClassPathXmlApplicationContext(「applicationContext.xml」); 我想這是造成這個問題。現在它是固定的。 非常感謝您的幫助。 –

相關問題