数据分发
前一篇文章已经说了数据采集器的背景以及设计原理,接下将说明数据采集的数据分发思想
核心实现
RouterMonitor 方法 doRouter(),对数据进行分发处理并返回处理结果,体现了类的单一职责
接下来就对这个方法的核心实现进行分析
package com.glufine.common;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.glufine.service.RouterBeanDefination;
/**
* 路由控制器
*
* @author syj
*
*/
@Component("routerMonitor")
public class RouterMonitor {
@Autowired
private RouterFactory routerFactory;
/**
* 执行分发工作
*/
public String doRouter(String value, byte[] sourceByte, Map<String, Object> session) {
// 获取指定的routerKey
RouterKey routerKey = routerFactory.fetchRouterKey(value, sourceByte);
if (routerKey == null) {
return "error";
}
RouterBeanDefination bean = findBeanDefination(routerKey);
if (bean != null) {
return bean.doWork(routerKey, session);
}
return "error";
};
/**
* 获取到对应的beanDefination 只获取第一个,接下的有用户自己去操作
* 规则:查询当前key,如果不存在,查询nextKey,如果不存在,返回null
*
* @param routerKey
* 路由➹
* @return
*/
private RouterBeanDefination findBeanDefination(RouterKey routerKey) {
// spring 命名规则
String beanId = creatSpringBeanId(routerKey.getRouterKeyName(), routerKey.getCurrentKey().getSpiltKey());
RouterBeanDefination bean = routerFactory.fetchRouterBeanDefination(beanId);
while (bean == null) {
RouterSplitDefination cuurentStep = routerKey.moveNextKey();
String splitKey = cuurentStep != null ? cuurentStep.getSpiltKey() : null;
if (splitKey == null) {
break;
}
beanId = creatSpringBeanId(routerKey.getRouterKeyName(), splitKey);
bean = routerFactory.fetchRouterBeanDefination(beanId);
}
return bean;
}
private String creatSpringBeanId(String id1, String id2) {
return id1 + id2;
}
}
1获取数据封装的 RouterKey ,那么RouterKey 是干什么的,就是对RouterKeyDefination+数据 进行实现,一个RouterKey中存储的是一条完整的指令数据
package com.glufine.common;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 路由➹
* @author syj
*
*/
public class RouterKey {
private RouterKeyDefination routerKeyDefination;
//要处理的字符串
private String sourceValue;
private String routerKeyName;
private Map<String, Object> dataMap;
private byte[] sourceByte;
//routerkey的结果集
private List<RouterSplitDefination> keyValues = new ArrayList<RouterSplitDefination>();
private volatile int currentStep = 0;
public RouterKey(RouterKeyDefination routerKeyDefination, String sourceValue,byte[] sourceByte) {
super();
this.routerKeyDefination = routerKeyDefination;
this.sourceValue = sourceValue;
this.routerKeyName = routerKeyDefination.getKeyName();
this.sourceByte = sourceByte;
cloneSplitDefination(routerKeyDefination.getKeyDefinations());
generateKeyValues(sourceValue);
}
private void cloneSplitDefination(List<RouterSplitDefination> keys){
for(RouterSplitDefination key:keys){
keyValues.add(key.clone());
}
}
/**
* 获取当前路由器名次
* @return
*/
public String getRouterKeyName() {
return routerKeyName;
}
//当前routerkey
public RouterSplitDefination getCurrentKey(){
return keyValues.get(currentStep);
}
public RouterSplitDefination getFirstKey(){
return keyValues.get(0);
}
//下一个routerkey
public RouterSplitDefination getNextKey(){
return keyValues.get(currentStep+1);
}
/**
* 返回下一个表达式,游标向下移动
* 如果不存在,则返回空,游标不动
* @return
*/
public RouterSplitDefination moveNextKey(){
currentStep += 1;
if(currentStep >= keyValues.size()){
currentStep -- ;
return null;
}
return keyValues.get(currentStep);
}
private void generateKeyValues( String sourceValue){
for(RouterSplitDefination keyDefination :keyValues){
keyDefination.genarateSplitVale(sourceValue);
}
}
public RouterKeyDefination getRouterKeyDefination() {
return routerKeyDefination;
}
public String getSourceValue() {
return sourceValue;
}
public int getCurrentStep() {
return currentStep;
}
public List<RouterSplitDefination> getKeyValues() {
return keyValues;
}
public byte[] getSourceByte() {
return sourceByte;
}
public void setSourceByte(byte[] sourceByte) {
this.sourceByte = sourceByte;
}
public void setSourceValue(String sourceValue) {
this.sourceValue = sourceValue;
}
/**
* 将数据包装成map集合
* @return
*/
public Map<String,Object> generateDataMap(){
if(dataMap == null){
dataMap = new HashMap<String,Object>();
for(RouterSplitDefination bean:keyValues){
dataMap.put(bean.getSpiltKey(), bean.getSplitValue());
}
}
return dataMap;
}
}
那么RouterKey 怎么获的呢,需要 routerFactory.fetchRouterKey(value, sourceByte); 在这个过程中,需要先去获取该指令的指令配置文件,然后把该指令的配置文件解析成RouterKeyDefination,然后根据RouterKeyDefination的配置内容,进行字符串分割,并将key-value保存到数据集合中
package com.glufine.common;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import com.glufine.service.RouterBeanDefination;
@Component("routerFactory")
public class RouterFactory implements ApplicationContextAware {
private ApplicationContext applicationContext;
/**
* 获取RouterKey
* @param value
* @return
*/
public RouterKey fetchRouterKey(String value,byte[] sourceByte){
RouterTable.newInstence();
Map<String,String> routerMapper = RouterTable.getRouterMapperMap();
Map<String,RouterKeyDefination> router = RouterTable.getRouterMap();
//获取一级路由分发器
RouterKeyDefination baseRouterKey = router.get("driverMapper");
RouterKey baseRouter = new RouterKey(baseRouterKey,value,sourceByte);
RouterSplitDefination baseRouterSplitDefination= baseRouter.getFirstKey();
String routerMapperValue = routerMapper.get(baseRouterSplitDefination.getSpiltKey()+baseRouterSplitDefination.getSplitValue());
//根据value获取指定的路由分发器
RouterKeyDefination routerkey = router.get(routerMapperValue);
if(routerkey==null){
return null;
}
RouterKey resultRouter = new RouterKey(routerkey,value,sourceByte);
return resultRouter;
}
public RouterBeanDefination fetchRouterBeanDefination(String beanId){
try {
return (RouterBeanDefination) applicationContext.getBean(beanId);
} catch (Exception e) {
// e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
// RouterFactory factory = new RouterFactory();
// factory.fetchRouterKey("5A18000000100000000111806607316020216250053");
System.out.println("5A18000000100000000111806607316020216250053".length());
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
为了方便RouterKeyDefination的获取,将多个指令集合进行抽象,抽象成RouterTable作为RouterKeyDefination的缓存package com.glufine.common;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.glufine.util.PropertiesUtil;
/**
* 路由表
* @author syj
*
*/
public class RouterTable {
public static RouterTable table = null;
public static RouterTable newInstence(){
if(table == null){
table = new RouterTable();
}
return table;
}
//
private static Map<String,String> routerMapperMap = new HashMap<String,String>();
private static Map<String,RouterKeyDefination> routerMap = new HashMap<String,RouterKeyDefination>();
private RouterTable() {
super();
//路由匹配规则
PropertiesUtil baseMapper = new PropertiesUtil("routeBaseMapper.properties");
generateRouterMapperMap(baseMapper.getAllProperty());
//路由key
PropertiesUtil router = new PropertiesUtil("route.properties");
generateRouterMap(router.getAllProperty());
}
/**
* 获取如有分发解析集合
* 规定特定的数据向分发到特定路由器
* @return
*/
public static Map<String, String> getRouterMapperMap() {
return routerMapperMap;
}
/**
* 获取所有的路由分发器
* @return
*/
public static Map<String, RouterKeyDefination> getRouterMap() {
return routerMap;
}
private void generateRouterMap(Map<String,String> maps){
Set<String> set = maps.keySet();
for(String key:set){
String value = maps.get(key);
String[] splitvalues = value.split(";");
RouterKeyDefination keyDefination = new RouterKeyDefination(key);
for(String splitvalue : splitvalues){
String[] result = splitvalue.split(",");
RouterSplitDefination bean = new RouterSplitDefination(result[0],
Integer.parseInt(result[1]),Integer.parseInt(result[2]));
keyDefination.putKey(bean);
}
routerMap.put(key, keyDefination);
}
};
private void generateRouterMapperMap(Map<String,String> maps){
Set<String> set = maps.keySet();
for(String key:set){
String value = maps.get(key);
String[] splitvalues = value.split(";");
for(String splitvalue : splitvalues){
String[] result = splitvalue.split(",");
routerMapperMap.put(result[0], result[1]);
}
}
}
public static void main(String[] args) {
RouterTable.newInstence();
}
}
RouterTable由于需要读取配置文件,所以采取单例的模式进行实现。这样则最大程度上减少IO消耗。在这,实现了从基本数据到RouterKey的封装,接下来会有工厂+策略的模式实现RouterBeanDefination的获取。RouterBeanDefination其实就是对于每一个数据业务逻辑的解析,获取到了数据。已经获取到了数据,接下来就是对于具体数据的操作。