All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lmax.disruptor.spring.boot.DisruptorAutoConfiguration Maven / Gradle / Ivy

There is a newer version: 1.0.2.RELEASE
Show newest version
package com.lmax.disruptor.spring.boot;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ThreadFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.OrderComparator;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.EventTranslatorOneArg;
import com.lmax.disruptor.EventTranslatorThreeArg;
import com.lmax.disruptor.EventTranslatorTwoArg;
import com.lmax.disruptor.WaitStrategy;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.EventHandlerGroup;
import com.lmax.disruptor.dsl.ProducerType;
import com.lmax.disruptor.spring.boot.annotation.EventRule;
import com.lmax.disruptor.spring.boot.config.EventHandlerDefinition;
import com.lmax.disruptor.spring.boot.config.Ini;
import com.lmax.disruptor.spring.boot.context.DisruptorEventAwareProcessor;
import com.lmax.disruptor.spring.boot.event.DisruptorApplicationEvent;
import com.lmax.disruptor.spring.boot.event.DisruptorEvent;
import com.lmax.disruptor.spring.boot.event.factory.DisruptorBindEventFactory;
import com.lmax.disruptor.spring.boot.event.factory.DisruptorEventThreadFactory;
import com.lmax.disruptor.spring.boot.event.handler.DisruptorEventDispatcher;
import com.lmax.disruptor.spring.boot.event.handler.DisruptorHandler;
import com.lmax.disruptor.spring.boot.event.handler.Nameable;
import com.lmax.disruptor.spring.boot.event.handler.chain.HandlerChainManager;
import com.lmax.disruptor.spring.boot.event.handler.chain.def.DefaultHandlerChainManager;
import com.lmax.disruptor.spring.boot.event.handler.chain.def.PathMatchingHandlerChainResolver;
import com.lmax.disruptor.spring.boot.event.translator.DisruptorEventOneArgTranslator;
import com.lmax.disruptor.spring.boot.event.translator.DisruptorEventThreeArgTranslator;
import com.lmax.disruptor.spring.boot.event.translator.DisruptorEventTwoArgTranslator;
import com.lmax.disruptor.spring.boot.hooks.DisruptorShutdownHook;
import com.lmax.disruptor.spring.boot.util.StringUtils;
import com.lmax.disruptor.spring.boot.util.WaitStrategys;

@Configuration
@ConditionalOnClass({ Disruptor.class })
@ConditionalOnProperty(prefix = DisruptorProperties.PREFIX, value = "enabled", havingValue = "true")
@EnableConfigurationProperties({ DisruptorProperties.class })
@SuppressWarnings({ "unchecked", "rawtypes" })
public class DisruptorAutoConfiguration implements ApplicationContextAware {

	private static final Logger LOG = LoggerFactory.getLogger(DisruptorAutoConfiguration.class);
	private ApplicationContext applicationContext;
	/**
	 * 处理器链定义
	 */
	private Map handlerChainDefinitionMap = new HashMap();
	
	/**
	 * 决定一个消费者将如何等待生产者将Event置入Disruptor的策略。用来权衡当生产者无法将新的事件放进RingBuffer时的处理策略。
	 * (例如:当生产者太快,消费者太慢,会导致生成者获取不到新的事件槽来插入新事件,则会根据该策略进行处理,默认会堵塞)
	 */
	@Bean
	@ConditionalOnMissingBean
	public WaitStrategy waitStrategy() {
		return WaitStrategys.YIELDING_WAIT;
	}

	@Bean
	@ConditionalOnMissingBean
	public ThreadFactory threadFactory() {
		return new DisruptorEventThreadFactory();
	}

	@Bean
	@ConditionalOnMissingBean
	public EventFactory eventFactory() {
		return new DisruptorBindEventFactory();
	}
	
	/**
	 * Handler实现集合
	 */
	@Bean("disruptorHandlers")
	public Map> disruptorHandlers() {

		Map> disruptorPreHandlers = new LinkedHashMap>();

		Map beansOfType = getApplicationContext().getBeansOfType(DisruptorHandler.class);
		if (!ObjectUtils.isEmpty(beansOfType)) {
			Iterator> ite = beansOfType.entrySet().iterator();
			while (ite.hasNext()) {
				Entry entry = ite.next();
				if (entry.getValue() instanceof DisruptorEventDispatcher) {
					// 跳过入口实现类
					continue;
				}
				
				EventRule annotationType = getApplicationContext().findAnnotationOnBean(entry.getKey(), EventRule.class);
				if(annotationType == null) {
					// 注解为空,则打印错误信息
					LOG.error("Not Found AnnotationType {0} on Bean {1} Whith Name {2}", EventRule.class, entry.getValue().getClass(), entry.getKey());
				} else {
					handlerChainDefinitionMap.put(annotationType.value(), entry.getKey());
				}
				
				disruptorPreHandlers.put(entry.getKey(), entry.getValue());
			}
		}
		// BeanFactoryUtils.beansOfTypeIncludingAncestors(getApplicationContext(),
		// EventHandler.class);

		return disruptorPreHandlers;
	}

	/**
	 * 处理器链集合
	 */
	@Bean("disruptorEventHandlers")
	public List disruptorEventHandlers(DisruptorProperties properties,
			@Qualifier("disruptorHandlers") Map> eventHandlers) {
		// 获取定义 拦截链规则
		List handlerDefinitions = properties.getHandlerDefinitions();
		// 拦截器集合
		List disruptorEventHandlers = new ArrayList();
		// 未定义,则使用默认规则
		if (CollectionUtils.isEmpty(handlerDefinitions)) {
			
			EventHandlerDefinition definition = new EventHandlerDefinition();
			
			definition.setOrder(0);
			definition.setDefinitionMap(handlerChainDefinitionMap);
			
			// 构造DisruptorEventHandler
			disruptorEventHandlers.add(this.createDisruptorEventHandler(definition, eventHandlers));
			
		} else {
			// 迭代拦截器规则
			for (EventHandlerDefinition handlerDefinition : handlerDefinitions) {
	
				// 构造DisruptorEventHandler
				disruptorEventHandlers.add(this.createDisruptorEventHandler(handlerDefinition, eventHandlers));
	
			}
		}
		// 进行排序
		Collections.sort(disruptorEventHandlers, new OrderComparator());

		return disruptorEventHandlers;
	}

	/**
	 * 
	 * @description : 构造DisruptorEventHandler
	 * @param handlerDefinition
	 * @param eventHandlers
	 * @return
	 */
	protected DisruptorEventDispatcher createDisruptorEventHandler(EventHandlerDefinition handlerDefinition,
			Map> eventHandlers) {

		if (StringUtils.isNotEmpty(handlerDefinition.getDefinitions())) {
			handlerChainDefinitionMap.putAll(this.parseHandlerChainDefinitions(handlerDefinition.getDefinitions()));
		} else if (!CollectionUtils.isEmpty(handlerDefinition.getDefinitionMap())) {
			handlerChainDefinitionMap.putAll(handlerDefinition.getDefinitionMap());
		}

		HandlerChainManager manager = createHandlerChainManager(eventHandlers, handlerChainDefinitionMap);
		PathMatchingHandlerChainResolver chainResolver = new PathMatchingHandlerChainResolver();
		chainResolver.setHandlerChainManager(manager);
		return new DisruptorEventDispatcher(chainResolver, handlerDefinition.getOrder());
	}

	protected Map parseHandlerChainDefinitions(String definitions) {
		Ini ini = new Ini();
		ini.load(definitions);
		Ini.Section section = ini.getSection("urls");
		if (CollectionUtils.isEmpty(section)) {
			section = ini.getSection(Ini.DEFAULT_SECTION_NAME);
		}
		return section;
	}

	protected HandlerChainManager createHandlerChainManager(
			Map> eventHandlers,
			Map handlerChainDefinitionMap) {

		HandlerChainManager manager = new DefaultHandlerChainManager();
		if (!CollectionUtils.isEmpty(eventHandlers)) {
			for (Map.Entry> entry : eventHandlers.entrySet()) {
				String name = entry.getKey();
				DisruptorHandler handler = entry.getValue();
				if (handler instanceof Nameable) {
					((Nameable) handler).setName(name);
				}
				manager.addHandler(name, handler);
			}
		}

		if (!CollectionUtils.isEmpty(handlerChainDefinitionMap)) {
			for (Map.Entry entry : handlerChainDefinitionMap.entrySet()) {
				// ant匹配规则
				String rule = entry.getKey();
				String chainDefinition = entry.getValue();
				manager.createChain(rule, chainDefinition);
			}
		}

		return manager;
	}

	/**
	 * http://blog.csdn.net/a314368439/article/details/72642653?utm_source=itdadao&utm_medium=referral
	 * 

* 创建Disruptor *

*

* 1 eventFactory 为 *

* 2 ringBufferSize为RingBuffer缓冲区大小,最好是2的指数倍 *

* * @param eventFactory * 工厂类对象,用于创建一个个的LongEvent, * LongEvent是实际的消费数据,初始化启动Disruptor的时候,Disruptor会调用该工厂方法创建一个个的消费数据实例存放到RingBuffer缓冲区里面去,创建的对象个数为ringBufferSize指定的 * @param ringBufferSize * RingBuffer缓冲区大小 * @param executor * 线程池,Disruptor内部的对数据进行接收处理时调用 * @param producerType * 用来指定数据生成者有一个还是多个,有两个可选值ProducerType.SINGLE和ProducerType.MULTI * @param waitStrategy * 一种策略,用来均衡数据生产者和消费者之间的处理效率,默认提供了3个实现类 */ @Bean @ConditionalOnClass({ Disruptor.class }) @ConditionalOnProperty(prefix = DisruptorProperties.PREFIX, value = "enabled", havingValue = "true") public Disruptor disruptor( DisruptorProperties properties, WaitStrategy waitStrategy, ThreadFactory threadFactory, EventFactory eventFactory, @Qualifier("disruptorEventHandlers") List disruptorEventHandlers) { Disruptor disruptor = null; if (properties.isMultiProducer()) { disruptor = new Disruptor(eventFactory, properties.getRingBufferSize(), threadFactory, ProducerType.MULTI, waitStrategy); } else { disruptor = new Disruptor(eventFactory, properties.getRingBufferSize(), threadFactory, ProducerType.SINGLE, waitStrategy); } if (!ObjectUtils.isEmpty(disruptorEventHandlers)) { // 进行排序 Collections.sort(disruptorEventHandlers, new OrderComparator()); // 使用disruptor创建消费者组 EventHandlerGroup handlerGroup = null; for (int i = 0; i < disruptorEventHandlers.size(); i++) { // 连接消费事件方法,其中EventHandler的是为消费者消费消息的实现类 DisruptorEventDispatcher eventHandler = disruptorEventHandlers.get(i); if(i < 1) { handlerGroup = disruptor.handleEventsWith(eventHandler); } else { // 完成前置事件处理之后执行后置事件处理 handlerGroup.then(eventHandler); } } } // 启动 disruptor.start(); /** * 应用退出时,要调用shutdown来清理资源,关闭网络连接,从MetaQ服务器上注销自己 * 注意:我们建议应用在JBOSS、Tomcat等容器的退出钩子里调用shutdown方法 */ Runtime.getRuntime().addShutdownHook(new DisruptorShutdownHook(disruptor)); return disruptor; } @Bean @ConditionalOnMissingBean public EventTranslatorOneArg oneArgEventTranslator() { return new DisruptorEventOneArgTranslator(); } @Bean @ConditionalOnMissingBean public EventTranslatorTwoArg twoArgEventTranslator() { return new DisruptorEventTwoArgTranslator(); } @Bean @ConditionalOnMissingBean public EventTranslatorThreeArg threeArgEventTranslator() { return new DisruptorEventThreeArgTranslator(); } @Bean public DisruptorTemplate disruptorTemplate() { return new DisruptorTemplate(); } @Bean public ApplicationListener disruptorEventListener(Disruptor disruptor, EventTranslatorOneArg oneArgEventTranslator) { return new ApplicationListener() { @Override public void onApplicationEvent(DisruptorApplicationEvent appEvent) { DisruptorEvent event = (DisruptorEvent) appEvent.getSource(); disruptor.publishEvent(oneArgEventTranslator, event); } }; } @Bean public DisruptorEventAwareProcessor disruptorEventAwareProcessor() { return new DisruptorEventAwareProcessor(); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public ApplicationContext getApplicationContext() { return applicationContext; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy