通过传入参数动态实现@JmsListener消息监听的功能

下面是一般的注解方法:

@JmsListener(destination = "Q_LOCATION", containerFactory = "locateQueueFactory")
public void handleMessage(final String message) {
    System.out.println(message);
}
@Configuration
@PropertySource(value = "file:/home/layui/resources/service.properties", encoding = "UTF-8")
public class ActiveMQconfig {

	@Value("${activemq-broker-url}")
	private String brokerUrl;
	
	@Value("${activemq-username}")
	private String username;
	
	@Value("${activemq-password}")
	private String password;

	@Value("${activemq-session-size}")
	private int sessionSize;
	
	@Bean
	public CachingConnectionFactory connectionFactory(){
		CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
		ActiveMQConnectionFactory af = new ActiveMQConnectionFactory(username, password, brokerUrl);
		//异步发送
		af.setUseAsyncSend(true);
		//消费者预取
		ActiveMQPrefetchPolicy prefetchPolicy = new ActiveMQPrefetchPolicy();
		prefetchPolicy.setQueuePrefetch(1000);
		prefetchPolicy.setMaximumPendingMessageLimit(100000);
		af.setPrefetchPolicy(prefetchPolicy);
		//批量确认
		af.setOptimizeAcknowledge(true);
		//重试次数
		RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
		redeliveryPolicy.setMaximumRedeliveries(3);
		af.setRedeliveryPolicy(redeliveryPolicy);

		connectionFactory.setTargetConnectionFactory(af);
		connectionFactory.setSessionCacheSize(100);
		return connectionFactory;
	}

	@Bean
	public JmsListenerContainerFactory locateQueueFactory(ConnectionFactory connectionFactory) {
		DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
		factory.setPubSubDomain(false);
		factory.setConnectionFactory(connectionFactory);
		factory.setConcurrency("10-100");
		factory.setTaskExecutor(new ThreadPoolExecutor(10, 100, 10, TimeUnit.MINUTES,
				new SynchronousQueue<>(), new NamedThreadFactory("notify-location-")));

		return factory;
	}
}

下面是动态实现监听的方法

package com.joysuch.hospital.server.activemq;

import com.alibaba.dubbo.common.utils.NamedThreadFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ActiveMQPrefetchPolicy;
import org.apache.activemq.RedeliveryPolicy;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jms.annotation.JmsListenerAnnotationBeanPostProcessor;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerEndpointRegistry;
import org.springframework.jms.config.SimpleJmsListenerEndpoint;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.stereotype.Component;

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.TextMessage;
import java.lang.reflect.Field;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class ActiveMqRecive implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void test(String DestinationName,String url,String username,String password) {
            SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
            endpoint.setId(DestinationName);
            endpoint.setDestination(DestinationName);
            endpoint.setMessageListener(message -> {
                try {
                    String text = ((TextMessage)message).getText();
                    System.out.println(Thread.currentThread().getName()+"获取到的消息为:"+text);
                    Thread.sleep(1000);
                } catch (InterruptedException | JMSException e) {
                    log.error("消息读取失败"+e.getMessage());
                }
            });

            try {
                DefaultJmsListenerContainerFactory beanFactory =  this.createJmsListenerContainerFactory(username, password, url);
                JmsListenerAnnotationBeanPostProcessor bean = applicationContext.getBean(JmsListenerAnnotationBeanPostProcessor.class);
                Field endpointRegistry = JmsListenerAnnotationBeanPostProcessor.class.getDeclaredField("endpointRegistry");
                endpointRegistry.setAccessible(true);
                JmsListenerEndpointRegistry registry = (JmsListenerEndpointRegistry) endpointRegistry.get(bean);
                registry.registerListenerContainer(endpoint,beanFactory, true);
            } catch (NoSuchFieldException | IllegalAccessException |IllegalStateException e) {
                log.error("MQ配置连接失败--->>>"+e.getMessage());
            }

    }
    /**
     * 通过参数创建工厂
     * @param DestinationName
     * @param url
     * @param username
     * @param password
     */
    private DefaultJmsListenerContainerFactory createJmsListenerContainerFactory(String USERNAME,String PASSWORD,String BROKEN_URL){
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        ActiveMQConnectionFactory af = new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKEN_URL);
        //异步发送
        af.setUseAsyncSend(true);
        //消费者预取
        ActiveMQPrefetchPolicy prefetchPolicy = new ActiveMQPrefetchPolicy();
        prefetchPolicy.setQueuePrefetch(1000);
        prefetchPolicy.setMaximumPendingMessageLimit(100000);
        af.setPrefetchPolicy(prefetchPolicy);
        //批量确认
        af.setOptimizeAcknowledge(true);
        //重试次数
        RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
        redeliveryPolicy.setMaximumRedeliveries(3);
        af.setRedeliveryPolicy(redeliveryPolicy);

        connectionFactory.setTargetConnectionFactory(af);
        connectionFactory.setSessionCacheSize(100);

        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setPubSubDomain(false);
        factory.setConnectionFactory(connectionFactory);
        factory.setConcurrency("10-100");
        factory.setTaskExecutor(new ThreadPoolExecutor(10, 100, 10, TimeUnit.MINUTES,
                new SynchronousQueue<>(), new NamedThreadFactory("notify-location-")));
        return factory;
    }

}

ps:也是通过公司大佬的帮助实现的功能,感谢强哥,哈哈哈~~~

你可能感兴趣的:(通过传入参数动态实现@JmsListener消息监听的功能)