Ver código fonte

优化cmd 完成

java110 5 anos atrás
pai
commit
145470f8c3
23 arquivos alterados com 1357 adições e 3 exclusões
  1. 29 0
      java110-core/src/main/java/com/java110/core/annotation/Java110Cmd.java
  2. 23 0
      java110-core/src/main/java/com/java110/core/annotation/Java110CmdDiscovery.java
  3. 195 0
      java110-core/src/main/java/com/java110/core/annotation/Java110CmdDiscoveryRegistrar.java
  4. 61 0
      java110-core/src/main/java/com/java110/core/context/AbstractCmdDataFlowContext.java
  5. 13 1
      java110-core/src/main/java/com/java110/core/context/AbstractDataFlowContextPlus.java
  6. 88 0
      java110-core/src/main/java/com/java110/core/context/CmdDataFlow.java
  7. 19 0
      java110-core/src/main/java/com/java110/core/context/ICmdDataFlowContext.java
  8. 2 0
      java110-core/src/main/java/com/java110/core/context/IDataFlowContextPlus.java
  9. 52 0
      java110-core/src/main/java/com/java110/core/event/cmd/AbstractServiceCmdListener.java
  10. 32 0
      java110-core/src/main/java/com/java110/core/event/cmd/CmdEvent.java
  11. 207 0
      java110-core/src/main/java/com/java110/core/event/cmd/ServiceCmdEventPublishing.java
  12. 20 0
      java110-core/src/main/java/com/java110/core/event/cmd/ServiceCmdListener.java
  13. 81 0
      java110-service/src/main/java/com/java110/service/api/CmdApi.java
  14. 24 0
      java110-service/src/main/java/com/java110/service/smo/ICmdServiceSMO.java
  15. 158 0
      java110-service/src/main/java/com/java110/service/smo/impl/CmdServiceSMOImpl.java
  16. 189 0
      java110-utils/src/main/java/com/java110/utils/exception/CmdException.java
  17. 5 2
      service-dev/src/main/java/com/java110/dev/DevServiceApplicationStart.java
  18. 25 0
      service-dev/src/main/java/com/java110/dev/cmd/SaveMappingCmd.java
  19. 80 0
      service-dev/src/main/resources/application-dev.yml
  20. 3 0
      service-dev/src/main/resources/application.yml
  21. 15 0
      service-dev/src/main/resources/banner.txt
  22. 33 0
      service-dev/src/main/resources/dataSource.yml
  23. 3 0
      service-dev/src/main/resources/java110.properties

+ 29 - 0
java110-core/src/main/java/com/java110/core/annotation/Java110Cmd.java

@@ -0,0 +1,29 @@
+package com.java110.core.annotation;
+
+import org.springframework.core.annotation.AliasFor;
+import org.springframework.stereotype.Component;
+
+import java.lang.annotation.*;
+
+/**
+ * Created by wuxw on 2018/7/2.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Component
+public @interface Java110Cmd {
+    @AliasFor("name")
+    String value() default "";
+
+    @AliasFor("value")
+    String name() default "";
+
+    /**
+     * 服务编码
+     * @return
+     */
+    String serviceCode();
+
+
+}

+ 23 - 0
java110-core/src/main/java/com/java110/core/annotation/Java110CmdDiscovery.java

@@ -0,0 +1,23 @@
+package com.java110.core.annotation;
+
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+/**
+ * 侦听注入
+ * Created by wuxw on 2018/7/2.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@Import(Java110CmdDiscoveryRegistrar.class)
+public @interface Java110CmdDiscovery {
+
+    String[] basePackages() default {};
+
+    String[] value() default {};
+
+    Class<?> cmdPublishClass();
+}

+ 195 - 0
java110-core/src/main/java/com/java110/core/annotation/Java110CmdDiscoveryRegistrar.java

@@ -0,0 +1,195 @@
+package com.java110.core.annotation;
+
+import com.java110.utils.util.Assert;
+import org.springframework.beans.factory.BeanClassLoaderAware;
+import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.core.type.filter.AnnotationTypeFilter;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.StringUtils;
+
+import java.beans.Introspector;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 自定义侦听扫描
+ * Created by wuxw on 2018/7/2.
+ */
+public class Java110CmdDiscoveryRegistrar implements ImportBeanDefinitionRegistrar,ResourceLoaderAware, BeanClassLoaderAware {
+
+    private ResourceLoader resourceLoader;
+
+    private ClassLoader classLoader;
+
+    public Java110CmdDiscoveryRegistrar(){
+
+    }
+
+    @Override
+    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
+        try {
+            registerListener(importingClassMetadata,registry);
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void setBeanClassLoader(ClassLoader classLoader) {
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    public void setResourceLoader(ResourceLoader resourceLoader) {
+        this.resourceLoader = resourceLoader;
+    }
+
+    /**
+     * 注册侦听
+     * @param metadata
+     * @param registry
+     */
+    public void registerListener(AnnotationMetadata metadata,
+                                 BeanDefinitionRegistry registry) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        ClassPathScanningCandidateComponentProvider scanner = getScanner();
+        scanner.setResourceLoader(this.resourceLoader);
+        Set<String> basePackages;
+        Map<String, Object> attrs = metadata
+                .getAnnotationAttributes(Java110CmdDiscovery.class.getName());
+
+        Object cmdPublishClassObj =  attrs.get("cmdPublishClass");
+
+        Assert.notNull(cmdPublishClassObj,"Java110CmdDiscovery 没有配置 cmdPublishClass 属性");
+
+        Class<?> cmdPublishClass = (Class<?>) cmdPublishClassObj;
+
+        AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
+                Java110Cmd.class);
+
+        scanner.addIncludeFilter(annotationTypeFilter);
+        basePackages = getBasePackages(metadata);
+
+        for (String basePackage : basePackages) {
+            Set<BeanDefinition> candidateComponents = scanner
+                    .findCandidateComponents(basePackage);
+            for (BeanDefinition candidateComponent : candidateComponents) {
+                if (candidateComponent instanceof AnnotatedBeanDefinition) {
+                    // verify annotated class is an interface
+                    AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
+                    AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
+
+
+                    Map<String, Object> attributes = annotationMetadata
+                            .getAnnotationAttributes(
+                                    Java110Cmd.class.getCanonicalName());
+
+                    String beanName = getListenerName(attributes,beanDefinition);
+
+                    /*BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(beanDefinition, beanName);
+                    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);*/
+                    Method method = cmdPublishClass.getMethod("addListener",String.class);
+                    method.invoke(null,beanName);
+                }
+            }
+        }
+    }
+
+    protected ClassPathScanningCandidateComponentProvider getScanner() {
+        return new ClassPathScanningCandidateComponentProvider(false) {
+
+            @Override
+            protected boolean isCandidateComponent(
+                    AnnotatedBeanDefinition beanDefinition) {
+                if (beanDefinition.getMetadata().isIndependent()) {
+                    // TODO until SPR-11711 will be resolved
+                    if (beanDefinition.getMetadata().isInterface()
+                            && beanDefinition.getMetadata()
+                            .getInterfaceNames().length == 1
+                            && Annotation.class.getName().equals(beanDefinition
+                            .getMetadata().getInterfaceNames()[0])) {
+                        try {
+                            Class<?> target = ClassUtils.forName(
+                                    beanDefinition.getMetadata().getClassName(),
+                                    Java110CmdDiscoveryRegistrar.this.classLoader);
+                            return !target.isAnnotation();
+                        }
+                        catch (Exception ex) {
+                            this.logger.error(
+                                    "Could not load target class: "
+                                            + beanDefinition.getMetadata().getClassName(),
+                                    ex);
+
+                        }
+                    }
+                    return true;
+                }
+                return false;
+
+            }
+        };
+    }
+
+    protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
+        Map<String, Object> attributes = importingClassMetadata
+                .getAnnotationAttributes(Java110CmdDiscovery.class.getCanonicalName());
+
+        Set<String> basePackages = new HashSet<String>();
+        for (String pkg : (String[]) attributes.get("value")) {
+            if (StringUtils.hasText(pkg)) {
+                basePackages.add(pkg);
+            }
+        }
+        for (String pkg : (String[]) attributes.get("basePackages")) {
+            if (StringUtils.hasText(pkg)) {
+                basePackages.add(pkg);
+            }
+        }
+        if (basePackages.isEmpty()) {
+            basePackages.add(
+                    ClassUtils.getPackageName(importingClassMetadata.getClassName()));
+        }
+        return basePackages;
+    }
+
+
+    /**
+     * 获取名称
+     * @param listeners
+     * @param beanDefinition
+     * @return
+     */
+    private String getListenerName(Map<String, Object> listeners,AnnotatedBeanDefinition beanDefinition) {
+        if (listeners == null) {
+            String shortClassName = ClassUtils.getShortName(beanDefinition.getBeanClassName());
+            return Introspector.decapitalize(shortClassName);
+        }
+        String value = (String) listeners.get("value");
+        if (!StringUtils.hasText(value)) {
+            value = (String) listeners.get("name");
+        }
+        if (StringUtils.hasText(value)) {
+            return value;
+        }
+
+        String shortClassName = ClassUtils.getShortName(beanDefinition.getBeanClassName());
+        value = Introspector.decapitalize(shortClassName);
+        return value;
+    }
+
+
+}

+ 61 - 0
java110-core/src/main/java/com/java110/core/context/AbstractCmdDataFlowContext.java

@@ -0,0 +1,61 @@
+package com.java110.core.context;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * 数据流上下文
+ * Created by wuxw on 2018/5/18.
+ */
+public abstract class AbstractCmdDataFlowContext extends AbstractDataFlowContextPlus implements ICmdDataFlowContext{
+
+    protected AbstractCmdDataFlowContext(){}
+
+    protected AbstractCmdDataFlowContext(Date startDate, String code) {
+
+    }
+
+
+
+
+    /**
+     * 构建 对象信息
+     * @param reqInfo
+     * @param headerAll
+     * @return
+     * @throws Exception
+     */
+    public  <T> T builder(String reqInfo, Map<String,String> headerAll) throws Exception{
+        //预处理
+        preBuilder(reqInfo, headerAll);
+        //调用builder
+        T dataFlowContext = (T)doBuilder(reqInfo, headerAll);
+        //后处理
+        afterBuilder((IOrderDataFlowContext) dataFlowContext);
+        return dataFlowContext;
+    }
+
+
+    /**
+     * 预处理
+     * @param reqInfo
+     * @param headerAll
+     */
+    protected void preBuilder(String reqInfo, Map<String,String> headerAll) {
+
+    }
+
+    /**
+     * 构建对象
+     * @param reqInfo
+     * @param headerAll
+     * @return
+     * @throws Exception
+     */
+    public abstract ICmdDataFlowContext doBuilder(String reqInfo, Map<String,String> headerAll) throws Exception;
+
+    protected void afterBuilder(IOrderDataFlowContext dataFlowContext){
+
+    }
+
+}

+ 13 - 1
java110-core/src/main/java/com/java110/core/context/AbstractDataFlowContextPlus.java

@@ -2,6 +2,7 @@ package com.java110.core.context;
 
 import com.alibaba.fastjson.JSONObject;
 
+import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -23,6 +24,8 @@ public abstract class AbstractDataFlowContextPlus implements IDataFlowContextPlu
      */
     private JSONObject reqJson;
 
+    private String reqData;
+
     /**
      * 返回头信息
      */
@@ -34,6 +37,7 @@ public abstract class AbstractDataFlowContextPlus implements IDataFlowContextPlu
     private JSONObject resJson;
 
 
+
     @Override
     public String getDataFlowId() {
         return dataFlowId;
@@ -49,6 +53,9 @@ public abstract class AbstractDataFlowContextPlus implements IDataFlowContextPlu
     }
 
     public void setReqHeaders(Map<String, String> reqHeaders) {
+        if(reqHeaders == null){
+            reqHeaders = new HashMap<>();
+        }
         this.reqHeaders = reqHeaders;
     }
 
@@ -82,6 +89,11 @@ public abstract class AbstractDataFlowContextPlus implements IDataFlowContextPlu
     }
 
 
+    public String getReqData() {
+        return reqData;
+    }
 
-
+    public void setReqData(String reqData) {
+        this.reqData = reqData;
+    }
 }

+ 88 - 0
java110-core/src/main/java/com/java110/core/context/CmdDataFlow.java

@@ -0,0 +1,88 @@
+package com.java110.core.context;
+
+import com.alibaba.fastjson.JSONObject;
+import com.java110.utils.constant.CommonConstant;
+import com.java110.utils.util.Assert;
+import com.java110.utils.util.DateUtil;
+import com.java110.utils.util.StringUtil;
+import org.springframework.http.ResponseEntity;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Cmd上下文实现
+ * Created by wuxw on 2018/4/13.
+ */
+public class CmdDataFlow extends AbstractCmdDataFlowContext {
+
+    public CmdDataFlow() {
+    }
+
+    public CmdDataFlow(Date startDate, String code) {
+        super(startDate, code);
+    }
+
+    private String serviceCode;
+
+    //rest 返回对象
+    private ResponseEntity responseEntity;
+
+    /**
+     * 构建 OrderDataFlow 对象
+     *
+     * @param reqInfo
+     * @param headerAll
+     * @return
+     * @throws Exception
+     */
+    public CmdDataFlow doBuilder(String reqInfo, Map<String, String> headerAll) throws Exception {
+        String serviceCode = headerAll.get(CommonConstant.HTTP_SERVICE);
+        Assert.hasLength(serviceCode, "未包含服务编码");
+        this.setDataFlowId(UUID.randomUUID().toString().replace("-", "").toLowerCase());
+        if (StringUtil.isJsonObject(reqInfo)) {
+            //赋值请求报文
+            this.setReqJson(JSONObject.parseObject(reqInfo));
+        } else {
+            this.setReqJson(new JSONObject());
+        }
+        this.setReqData(reqInfo);
+
+        this.setServiceCode(serviceCode);
+        //赋值 请求头信息
+        this.setReqHeaders(headerAll);
+        //构建返回头
+        builderResHeaders();
+
+        return this;
+    }
+
+    /**
+     * 构建返回头信息
+     */
+    private void builderResHeaders() {
+        Map<String, String> tmpResHeaders = new HashMap<String, String>();
+        tmpResHeaders.put(CommonConstant.HTTP_TRANSACTION_ID, this.getReqHeaders().get(CommonConstant.HTTP_TRANSACTION_ID));
+        tmpResHeaders.put(CommonConstant.HTTP_RES_TIME, DateUtil.getyyyyMMddhhmmssDateString());
+        this.setResHeaders(tmpResHeaders);
+    }
+
+    @Override
+    public String getServiceCode() {
+        return serviceCode;
+    }
+
+    public void setServiceCode(String serviceCode) {
+        this.serviceCode = serviceCode;
+    }
+
+    public ResponseEntity getResponseEntity() {
+        return responseEntity;
+    }
+
+    public void setResponseEntity(ResponseEntity responseEntity) {
+        this.responseEntity = responseEntity;
+    }
+}

+ 19 - 0
java110-core/src/main/java/com/java110/core/context/ICmdDataFlowContext.java

@@ -0,0 +1,19 @@
+package com.java110.core.context;
+
+import org.springframework.http.ResponseEntity;
+
+/**
+ * 数据上下文对象
+ */
+public interface ICmdDataFlowContext extends IDataFlowContextPlus{
+    /**
+     * 获取字符串请求报文 以防 请求报文不是json
+     *
+     * @return
+     */
+    String getReqData();
+
+    ResponseEntity getResponseEntity();
+
+    void setResponseEntity(ResponseEntity responseEntity);
+}

+ 2 - 0
java110-core/src/main/java/com/java110/core/context/IDataFlowContextPlus.java

@@ -10,6 +10,8 @@ import java.util.Map;
  */
 public interface IDataFlowContextPlus {
 
+    String getServiceCode();
+
 
     /**
      * 获取dataflowId

+ 52 - 0
java110-core/src/main/java/com/java110/core/event/cmd/AbstractServiceCmdListener.java

@@ -0,0 +1,52 @@
+package com.java110.core.event.cmd;
+
+import com.alibaba.fastjson.JSONObject;
+import com.java110.core.context.ICmdDataFlowContext;
+import com.java110.utils.exception.CmdException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public abstract class AbstractServiceCmdListener implements ServiceCmdListener {
+
+    private static Logger logger = LoggerFactory.getLogger(AbstractServiceCmdListener.class);
+
+    @Override
+    public void cmd(CmdEvent event) throws CmdException {
+        //这里处理业务逻辑数据
+        ICmdDataFlowContext dataFlowContext = event.getCmdDataFlowContext();
+        //获取请求数据
+        JSONObject reqJson = dataFlowContext.getReqJson();
+
+        logger.debug("API服务 --- 请求参数为:{}", reqJson.toJSONString());
+
+        validate(event, dataFlowContext,reqJson);
+
+        doCmd(event, dataFlowContext, reqJson);
+
+        //logger.debug("API服务 --- 返回报文信息:{}", dataFlowContext.getResponseEntity());
+    }
+
+    /**
+     * 数据格式校验方法
+     * @param event 事件对象
+     * @param cmdDataFlowContext 请求报文数据
+     */
+    protected abstract void validate(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson);
+
+
+    /**
+     * 业务处理类
+     * @param event  事件对象
+     * @param cmdDataFlowContext 数据上文对象
+     * @param reqJson 请求报文
+     */
+    protected abstract void doCmd(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException;
+
+
+    @Override
+    public int getOrder() {
+        return 0;
+    }
+
+}

+ 32 - 0
java110-core/src/main/java/com/java110/core/event/cmd/CmdEvent.java

@@ -0,0 +1,32 @@
+package com.java110.core.event.cmd;
+
+import com.java110.core.context.DataFlowContext;
+import com.java110.core.context.ICmdDataFlowContext;
+import com.java110.entity.center.AppService;
+
+import java.util.EventObject;
+
+/**
+ *
+ * 服务事件
+ * Created by wuxw on 2018/5/18.
+ */
+public class CmdEvent extends EventObject {
+
+    private ICmdDataFlowContext cmdDataFlowContext;
+    /**
+     * Constructs a prototypical Event.
+     *
+     * @param source The object on which the Event initially occurred.
+     * @throws IllegalArgumentException if source is null.
+     */
+    public CmdEvent(Object source, ICmdDataFlowContext cmdDataFlowContext) {
+        super(source);
+        this.cmdDataFlowContext = cmdDataFlowContext;
+
+    }
+
+    public ICmdDataFlowContext getCmdDataFlowContext() {
+        return cmdDataFlowContext;
+    }
+}

+ 207 - 0
java110-core/src/main/java/com/java110/core/event/cmd/ServiceCmdEventPublishing.java

@@ -0,0 +1,207 @@
+package com.java110.core.event.cmd;
+
+import com.java110.core.annotation.Java110Cmd;
+import com.java110.core.context.DataFlowContext;
+import com.java110.core.context.ICmdDataFlowContext;
+import com.java110.core.event.center.DataFlowListenerOrderComparator;
+import com.java110.core.event.service.api.ServiceDataFlowEvent;
+import com.java110.core.event.service.api.ServiceDataFlowListener;
+import com.java110.entity.center.AppService;
+import com.java110.utils.constant.CommonConstant;
+import com.java110.utils.constant.ResponseConstant;
+import com.java110.utils.constant.ServiceCodeConstant;
+import com.java110.utils.exception.BusinessException;
+import com.java110.utils.exception.CmdException;
+import com.java110.utils.exception.ListenerExecuteException;
+import com.java110.utils.factory.ApplicationContextFactory;
+import com.java110.utils.log.LoggerEngine;
+import com.java110.utils.util.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpMethod;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+/**
+ * 数据流 事件发布
+ * Created by wuxw on 2018/4/17.
+ */
+public class ServiceCmdEventPublishing {
+    private static Logger logger = LoggerFactory.getLogger(ServiceCmdEventPublishing.class);
+
+    private static Executor taskExecutor;
+
+    //默认 线程数 100
+    private static final int DEFAULT_THREAD_NUM = 100;
+
+    /**
+     * 保存侦听实例信息,一般启动时加载
+     */
+    private static final List<String> listeners = new ArrayList<String>();
+
+    /**
+     * 根据 事件类型查询侦听
+     */
+    private static final Map<String, List<ServiceCmdListener>> cacheListenersMap = new HashMap<String, List<ServiceCmdListener>>();
+
+    /**
+     * 添加 侦听,这个只有启动时,单线程 处理,所以是线程安全的
+     *
+     * @param listener
+     */
+    public static void addListener(String listener) {
+        listeners.add(listener);
+    }
+
+    /**
+     * 获取侦听(全部侦听)
+     *
+     * @return
+     */
+    public static List<String> getListeners() {
+        return listeners;
+    }
+
+    /**
+     * 根据是否实现了某个接口,返回侦听
+     *
+     * @param serviceCode
+     * @return
+     * @since 1.8
+     */
+    public static List<ServiceCmdListener> getListeners(String serviceCode) {
+
+        Assert.hasLength(serviceCode, "获取需要发布的事件处理侦听时,传递事件为空,请检查");
+
+        String needCachedServiceCode = serviceCode;
+        //先从缓存中获取,为了提升效率
+        if (cacheListenersMap.containsKey(needCachedServiceCode)) {
+            return cacheListenersMap.get(needCachedServiceCode);
+        }
+
+        List<ServiceCmdListener> cmdListeners = new ArrayList<ServiceCmdListener>();
+        for (String listenerBeanName : getListeners()) {
+            ServiceCmdListener listener = ApplicationContextFactory.getBean(listenerBeanName, ServiceCmdListener.class);
+            Java110Cmd java110Cmd = listener.getClass().getDeclaredAnnotation(Java110Cmd.class);
+            if(java110Cmd.serviceCode().equals(serviceCode)) {
+                cmdListeners.add(listener);
+            }
+        }
+
+        //这里排序
+        DataFlowListenerOrderComparator.sort(cmdListeners);
+
+
+        //将数据放入缓存中
+        if (cmdListeners.size() > 0) {
+            cacheListenersMap.put(needCachedServiceCode, cmdListeners);
+        }
+        return cmdListeners;
+    }
+
+
+    /**
+     * 发布事件
+     *
+     * @param cmdDataFlowContext
+     */
+    public static void multicastEvent(ICmdDataFlowContext cmdDataFlowContext) throws BusinessException {
+        Assert.notNull(cmdDataFlowContext.getServiceCode(), "当前没有可处理的业务信息!");
+        multicastEvent(cmdDataFlowContext.getServiceCode(), cmdDataFlowContext, null);
+    }
+
+
+    /**
+     * 发布事件
+     *
+     * @param serviceCode
+     * @param dataFlowContext
+     */
+    public static void multicastEvent(String serviceCode, ICmdDataFlowContext dataFlowContext) throws BusinessException {
+        multicastEvent(serviceCode, dataFlowContext,  null);
+    }
+
+    /**
+     * 发布事件
+     *
+     * @param serviceCode
+     * @param dataFlowContext 这个订单信息,以便于 侦听那边需要用
+     */
+    public static void multicastEvent(String serviceCode, ICmdDataFlowContext dataFlowContext, String asyn) throws BusinessException {
+        try {
+            CmdEvent targetDataFlowEvent = new CmdEvent(serviceCode, dataFlowContext);
+
+            multicastEvent(serviceCode, targetDataFlowEvent, asyn);
+        } catch (Exception e) {
+            logger.error("发布侦听失败,失败原因为:", e);
+            throw new BusinessException(ResponseConstant.RESULT_CODE_INNER_ERROR, e.getMessage());
+        }
+
+    }
+
+
+    /**
+     * 发布事件
+     *
+     * @param event
+     * @param asyn  A 表示异步处理
+     */
+    public static void multicastEvent(String serviceCode, final CmdEvent event, String asyn) {
+        List<ServiceCmdListener> listeners = getListeners(serviceCode);
+        //这里判断 serviceCode + httpMethod 的侦听,如果没有注册直接报错。
+        if (listeners == null || listeners.size() == 0) {
+            throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR,
+                    "服务【" + serviceCode + "】当前不支持");
+        }
+        for (final ServiceCmdListener listener : listeners) {
+
+            if (CommonConstant.PROCESS_ORDER_ASYNCHRONOUS.equals(asyn)) { //异步处理
+
+                Executor executor = getTaskExecutor();
+                executor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        invokeListener(listener, event);
+                    }
+                });
+                break;
+            } else {
+                invokeListener(listener, event);
+                break;
+            }
+        }
+    }
+
+
+    /**
+     * Return the current task executor for this multicaster.
+     */
+    protected static synchronized Executor getTaskExecutor() {
+        if (taskExecutor == null) {
+            taskExecutor = Executors.newFixedThreadPool(DEFAULT_THREAD_NUM);
+        }
+        return taskExecutor;
+    }
+
+    /**
+     * Invoke the given listener with the given event.
+     *
+     * @param listener the ApplicationListener to invoke
+     * @param event    the current event to propagate
+     * @since 4.1
+     */
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    protected static void invokeListener(ServiceCmdListener listener, CmdEvent event) {
+        try {
+            listener.cmd(event);
+        } catch (CmdException e) {
+            LoggerEngine.error("发布侦听失败", e);
+            throw e;
+        }
+    }
+}

+ 20 - 0
java110-core/src/main/java/com/java110/core/event/cmd/ServiceCmdListener.java

@@ -0,0 +1,20 @@
+package com.java110.core.event.cmd;
+
+import com.java110.core.event.app.order.Ordered;
+import com.java110.utils.exception.CmdException;
+
+import java.util.EventListener;
+
+/**
+ * 通用事件处理,
+ * Created by wuxw on 2018/4/17.
+ */
+public interface ServiceCmdListener extends EventListener, Ordered {
+
+    /**
+     * 执行指令
+     * @param event
+     * @throws Exception
+     */
+     void cmd(CmdEvent event) throws CmdException;
+}

+ 81 - 0
java110-service/src/main/java/com/java110/service/api/CmdApi.java

@@ -0,0 +1,81 @@
+package com.java110.service.api;
+
+import com.java110.core.base.controller.BaseController;
+import com.java110.core.factory.DataTransactionFactory;
+import com.java110.service.context.DataQuery;
+import com.java110.service.context.DataQueryFactory;
+import com.java110.service.smo.ICmdServiceSMO;
+import com.java110.service.smo.IQueryServiceSMO;
+import com.java110.utils.constant.CommonConstant;
+import com.java110.utils.constant.ResponseConstant;
+import com.java110.utils.util.Assert;
+import com.java110.vo.ResultVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 查询服务
+ * add by wuxw on 2018/4/20.
+ * modify by wuxw on 2019/4/20.
+ *
+ * @version 1.1
+ */
+@RestController
+@RequestMapping(path = "/cmd")
+public class CmdApi extends BaseController {
+
+    private final static Logger logger = LoggerFactory.getLogger(CmdApi.class);
+
+    @Autowired
+    private ICmdServiceSMO cmdServiceSMOImpl;
+
+
+    @RequestMapping(path = "/{service:.+}", method = RequestMethod.POST)
+    public ResponseEntity<String> service(@PathVariable String service,
+                                          @RequestBody String postInfo,
+                                          HttpServletRequest request) {
+        ResponseEntity<String> responseEntity = null;
+        Map<String, String> headers = new HashMap<String, String>();
+        try {
+
+            this.getRequestInfo(request, headers);
+            headers.put(CommonConstant.HTTP_SERVICE, service);
+            headers.put(CommonConstant.HTTP_METHOD, CommonConstant.HTTP_METHOD_POST);
+            logger.debug("api:{} 请求报文为:{},header信息为:{}", service, postInfo, headers);
+            responseEntity = cmdServiceSMOImpl.cmd(postInfo, headers);
+        } catch (Throwable e) {
+            logger.error("请求post 方法[" + service + "]失败:" + postInfo, e);
+            responseEntity = new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+        logger.debug("cmd:{} 返回信息为:{}", service, responseEntity);
+        return responseEntity;
+    }
+    /**
+     * 获取请求信息
+     *
+     * @param request
+     * @param headers
+     * @throws RuntimeException
+     */
+    private void getRequestInfo(HttpServletRequest request, Map headers) throws Exception {
+        try {
+            super.initHeadParam(request, headers);
+            super.initUrlParam(request, headers);
+        } catch (Exception e) {
+            logger.error("加载头信息失败", e);
+            throw e;
+        }
+    }
+
+}

+ 24 - 0
java110-service/src/main/java/com/java110/service/smo/ICmdServiceSMO.java

@@ -0,0 +1,24 @@
+package com.java110.service.smo;
+
+import com.java110.service.context.DataQuery;
+import com.java110.utils.exception.BusinessException;
+import com.java110.utils.exception.CmdException;
+import com.java110.utils.exception.SMOException;
+import org.springframework.http.ResponseEntity;
+
+import java.util.Map;
+
+/**
+ * 公用查询处理
+ * Created by wuxw on 2018/4/19.
+ */
+public interface ICmdServiceSMO {
+
+    /**
+     * 业务统一处理服务方法
+     * @param reqJson 请求报文json
+     * @return
+     */
+    ResponseEntity<String> cmd(String reqJson, Map<String, String> headers) throws Exception;
+
+}

+ 158 - 0
java110-service/src/main/java/com/java110/service/smo/impl/CmdServiceSMOImpl.java

@@ -0,0 +1,158 @@
+package com.java110.service.smo.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.java110.core.client.RestTemplate;
+import com.java110.core.context.CmdDataFlow;
+import com.java110.core.context.DataFlow;
+import com.java110.core.context.ICmdDataFlowContext;
+import com.java110.core.event.cmd.ServiceCmdEventPublishing;
+import com.java110.core.factory.DataFlowFactory;
+import com.java110.core.smo.ISaveTransactionLogSMO;
+import com.java110.entity.center.DataFlowLinksCost;
+import com.java110.service.smo.ICmdServiceSMO;
+import com.java110.utils.cache.MappingCache;
+import com.java110.utils.constant.KafkaConstant;
+import com.java110.utils.constant.MappingConstant;
+import com.java110.utils.exception.BusinessException;
+import com.java110.utils.exception.SMOException;
+import com.java110.utils.kafka.KafkaFactory;
+import com.java110.utils.log.LoggerEngine;
+import com.java110.utils.util.DateUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * cmd服务处理类
+ * Created by wuxw on 2018/4/13.
+ */
+@Service("cmdServiceSMOImpl")
+public class CmdServiceSMOImpl extends LoggerEngine implements ICmdServiceSMO {
+
+    private static Logger logger = LoggerFactory.getLogger(ICmdServiceSMO.class);
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @Autowired
+    private RestTemplate outRestTemplate;
+
+    @Autowired
+    private ISaveTransactionLogSMO saveTransactionLogSMOImpl;
+
+
+    /**
+     * 服务调度
+     *
+     * @param reqJson 请求报文json
+     * @param headers
+     * @return
+     * @throws SMOException
+     */
+    @Override
+    public ResponseEntity<String> cmd(String reqJson, Map<String, String> headers) throws Exception {
+
+        ICmdDataFlowContext cmdDataFlowContext = null;
+
+        Date startDate = DateUtil.getCurrentDate();
+
+        ResponseEntity<String> responseEntity = null;
+
+        String resJson = "";
+
+
+        //1.0 创建数据流 appId serviceCode
+        cmdDataFlowContext = DataFlowFactory.newInstance(CmdDataFlow.class).builder(reqJson, headers);
+
+
+        //6.0 调用下游系统
+        invokeBusinessSystem(cmdDataFlowContext);
+
+        responseEntity = cmdDataFlowContext.getResponseEntity();
+
+        Date endDate = DateUtil.getCurrentDate();
+
+        if (responseEntity == null) {
+            //resJson = encrypt(responseJson.toJSONString(),headers);
+            responseEntity = new ResponseEntity<String>(resJson, HttpStatus.OK);
+        }
+        return responseEntity;
+    }
+
+
+    /**
+     * 6.0 调用下游系统
+     *
+     * @param cmdDataFlowContext
+     * @throws BusinessException
+     */
+    private void invokeBusinessSystem(ICmdDataFlowContext cmdDataFlowContext) throws BusinessException {
+        ServiceCmdEventPublishing.multicastEvent(cmdDataFlowContext);
+    }
+
+
+    /**
+     * 保存日志信息
+     *
+     * @param requestJson
+     */
+    private void saveLogMessage(String requestJson, String responseJson) {
+
+        try {
+            if (MappingConstant.VALUE_ON.equals(MappingCache.getValue(MappingConstant.KEY_LOG_ON_OFF))) {
+                JSONObject log = new JSONObject();
+                log.put("request", requestJson);
+                log.put("response", responseJson);
+                KafkaFactory.sendKafkaMessage(KafkaConstant.TOPIC_LOG_NAME, "", log.toJSONString());
+            }
+        } catch (Exception e) {
+            logger.error("报错日志出错了,", e);
+        }
+    }
+
+    /**
+     * 保存耗时信息
+     *
+     * @param cmdDataFlowContext
+     */
+    private void saveCostTimeLogMessage(DataFlow cmdDataFlowContext) {
+        try {
+            if (MappingConstant.VALUE_ON.equals(MappingCache.getValue(MappingConstant.KEY_COST_TIME_ON_OFF))) {
+                List<DataFlowLinksCost> cmdDataFlowContextLinksCosts = cmdDataFlowContext.getLinksCostDates();
+                JSONObject costDate = new JSONObject();
+                JSONArray costDates = new JSONArray();
+                JSONObject newObj = null;
+                for (DataFlowLinksCost cmdDataFlowContextLinksCost : cmdDataFlowContextLinksCosts) {
+                    newObj = JSONObject.parseObject(JSONObject.toJSONString(cmdDataFlowContextLinksCost));
+                    newObj.put(" cmdDataFlowContextId", cmdDataFlowContext.getDataFlowId());
+                    newObj.put("transactionId", cmdDataFlowContext.getTransactionId());
+                    costDates.add(newObj);
+                }
+                costDate.put("costDates", costDates);
+
+                KafkaFactory.sendKafkaMessage(KafkaConstant.TOPIC_COST_TIME_LOG_NAME, "", costDate.toJSONString());
+            }
+        } catch (Exception e) {
+            logger.error("报错日志出错了,", e);
+        }
+    }
+
+
+    public RestTemplate getRestTemplate() {
+        return restTemplate;
+    }
+
+    public void setRestTemplate(RestTemplate restTemplate) {
+        this.restTemplate = restTemplate;
+    }
+
+}

+ 189 - 0
java110-utils/src/main/java/com/java110/utils/exception/CmdException.java

@@ -0,0 +1,189 @@
+package com.java110.utils.exception;
+
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * 侦听执行异常
+ * Created by wuxw on 2018/4/14.
+ */
+public class CmdException extends RuntimeException {
+
+
+    private Result result;
+    private Throwable cause = this;
+
+    public CmdException(){}
+
+    /**
+     * 构造方法
+     * @param result 返回值
+     * @param cause  异常堆栈
+     */
+    public CmdException(Result result, Throwable cause) {
+        super(result.getMsg(), cause);
+        this.result = result;
+    }
+
+    /**
+     * 构造方法
+     * @param code 返回码
+     * @param msg  错误消息
+     */
+    public CmdException(int code, String msg) {
+        super(msg);
+        this.result = new Result(code, msg);
+    }
+
+    public CmdException(String code, String msg) {
+        super(msg);
+        this.result = new Result(code, msg);
+    }
+
+    /**
+     * 构造方法
+     * @param result 返回值
+     * @param detail 具体的返回消息
+     */
+    public CmdException(Result result, String detail) {
+        super(result.getMsg() + "," + detail);
+        this.result = new Result(result.getCode(), result.getMsg() + "," + detail);
+    }
+
+    /**
+     * 构造方法
+     * @param result 返回值
+     * @param detail 具体的返回消息
+     * @param cause  异常堆栈
+     */
+    public CmdException(Result result, String detail, Throwable cause) {
+        super(result.getMsg() + "," + detail, cause);
+        this.result = new Result(result.getCode(), result.getMsg() + "," + detail);
+    }
+
+    /**
+     * 构造方法
+     * @param code	返回码
+     * @param msg	返回消息
+     * @param cause 异常堆栈
+     */
+    public CmdException(int code, String msg, Throwable cause) {
+        super(msg, cause);
+
+        if(cause != null) {
+            if(cause.getCause() != null) {
+                msg += " cause:" + ExceptionUtils.populateExecption(cause.getCause(), 500);
+            }
+            msg += " StackTrace:"+ExceptionUtils.populateExecption(cause, 500);
+        }
+        this.result = new Result(code, msg);
+    }
+
+    /**
+     * 构造方法
+     * @param code	返回码
+     * @param cause	异常堆栈
+     */
+    public CmdException(int code, Throwable cause) {
+        super(cause);
+        String msg = "";
+
+        if(cause != null) {
+            if(cause.getCause() != null) {
+                msg += " cause:" + ExceptionUtils.populateExecption(cause.getCause(), 500);
+            }
+            msg += " StackTrace:"+ExceptionUtils.populateExecption(cause, 500);
+        }
+        this.result = new Result(code, msg);
+    }
+
+    /**
+     *
+     * TODO 简单描述该方法的实现功能(可选).
+     * @see Throwable#getCause()
+     */
+    public synchronized Throwable getCause() {
+        return (cause==this ? super.getCause() : cause);
+    }
+
+
+    /**
+     * 返回异常消息
+     * @return 异常消息
+     */
+    @Override
+    public String getMessage() {
+        return ExceptionUtils.buildMessage(super.getMessage(), getCause());
+    }
+
+    /**
+     * 异常
+     * @return
+     */
+    public String toJsonString() {
+        JSONObject exceptionJson = JSONObject.parseObject("{\"exception\":{}");
+        JSONObject exceptionJsonObj = exceptionJson.getJSONObject("exception");
+
+        if (getResult() != null)
+            exceptionJsonObj.putAll(JSONObject.parseObject(result.toString()));
+
+        exceptionJsonObj.put("exceptionTrace",getMessage());
+
+        return exceptionJsonObj.toString();
+    }
+    @Override
+    public void printStackTrace(PrintStream ps) {
+        ps.print("<exception>");
+        if (getResult() != null) {
+            ps.print(result.toString());
+        }
+        ps.append("<exceptionTrace>");
+
+        Throwable cause = getCause();
+        if (cause == null) {
+            super.printStackTrace(ps);
+        } else {
+            ps.println(this);
+            ps.print("Caused by: ");
+            cause.printStackTrace(ps);
+        }
+        ps.append("</exceptionTrace>");
+        ps.println("</exception>");
+    }
+
+    @Override
+    public void printStackTrace(PrintWriter pw) {
+        pw.print("<exception>");
+        if (getResult() != null) {
+            pw.print(result.toString());
+        }
+        pw.append("<exceptionTrace>");
+
+        Throwable cause = getCause();
+        if (cause == null) {
+            super.printStackTrace(pw);
+        } else {
+            pw.println(this);
+            pw.print("Caused by: ");
+            cause.printStackTrace(pw);
+        }
+        pw.append("</exceptionTrace>");
+        pw.println("</exception>");
+    }
+
+    /**
+     * 返回异常值
+     * @return	异常值对象
+     */
+    public Result getResult() {
+        return result;
+    }
+
+    public void setResult(Result result) {
+        this.result = result;
+    }
+
+}

+ 5 - 2
service-dev/src/main/java/com/java110/dev/DevServiceApplicationStart.java

@@ -1,7 +1,10 @@
 package com.java110.dev;
 
+import com.java110.core.annotation.Java110CmdDiscovery;
 import com.java110.core.annotation.Java110ListenerDiscovery;
 import com.java110.core.client.RestTemplate;
+import com.java110.core.event.cmd.ServiceCmdEventPublishing;
+import com.java110.core.event.cmd.ServiceCmdListener;
 import com.java110.core.event.service.BusinessServiceDataFlowEventPublishing;
 import com.java110.service.init.ServiceStartInit;
 import org.slf4j.Logger;
@@ -34,8 +37,8 @@ import java.nio.charset.Charset;
         exclude = {LiquibaseAutoConfiguration.class,
                 org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class})
 @EnableDiscoveryClient
-@Java110ListenerDiscovery(listenerPublishClass = BusinessServiceDataFlowEventPublishing.class,
-        basePackages = {"com.java110.dev.listener"})
+@Java110CmdDiscovery(cmdPublishClass = ServiceCmdEventPublishing.class,
+        basePackages = {"com.java110.dev.cmd"})
 @EnableFeignClients(basePackages = {"com.java110.intf.user",
         "com.java110.intf.order",
         "com.java110.intf.common",

+ 25 - 0
service-dev/src/main/java/com/java110/dev/cmd/SaveMappingCmd.java

@@ -0,0 +1,25 @@
+package com.java110.dev.cmd;
+
+import com.alibaba.fastjson.JSONObject;
+import com.java110.core.annotation.Java110Cmd;
+import com.java110.core.context.ICmdDataFlowContext;
+import com.java110.core.event.cmd.AbstractServiceCmdListener;
+import com.java110.core.event.cmd.CmdEvent;
+import com.java110.utils.exception.CmdException;
+
+/**
+ * 保存编码映射处理类
+ */
+@Java110Cmd(serviceCode = "mapping.saveMapping")
+public class SaveMappingCmd extends AbstractServiceCmdListener {
+
+    @Override
+    protected void validate(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) {
+
+    }
+
+    @Override
+    protected void doCmd(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException {
+
+    }
+}

+ 80 - 0
service-dev/src/main/resources/application-dev.yml

@@ -0,0 +1,80 @@
+jedis:
+  pool:
+    config:
+      maxTotal: 100
+      maxIdle: 20
+      maxWaitMillis: 20000
+    host: dev.redis.java110.com
+    port: 6379
+    timeout: 3000
+    password: hc
+
+eureka:
+  instance:
+    leaseRenewalIntervalInSeconds: 10
+    leaseExpirationDurationInSeconds: 30
+    preferIpAddress: true
+    instanceId: ${spring.cloud.client.ip-address}:${server.port}
+  client:
+    serviceUrl:
+      defaultZone: http://dev.java110.com:8761/eureka/
+      #defaultZone: http://localhost:8761/eureka/
+server:
+  port: 8012
+  tomcat:
+    uri-encoding: UTF-8
+
+spring:
+  profiles:
+    active: share
+  http:
+    encoding:
+      charset: UTF-8
+      enabled: true
+      force: true
+  application:
+    name: dev-service
+  redis:
+    database: 0
+    host: dev.redis.java110.com
+    port: 6379
+    password: hc
+    pool:
+      max-active: 300
+      max-wait: 10000
+      max-idle: 100
+      min-idle: 0
+      timeout: 0
+
+
+#============== kafka ===================
+kafka:
+  consumer:
+    zookeeper:
+      connect: dev.zk.java110.com:2181
+    servers: dev.kafka.java110.com:9092
+    enable:
+      auto:
+        commit: true
+    session:
+      timeout: 6000
+    auto:
+      commit:
+        interval: 100
+      offset:
+        reset: latest
+    topic: test
+    group:
+      id: reportBusinessStatus
+    concurrency: 10
+
+  producer:
+    zookeeper:
+      connect: dev.zk.java110.com:2181
+    servers: dev.kafka.java110.com:9092
+    retries: 0
+    batch:
+      size: 4096
+    linger: 1
+    buffer:
+      memory: 40960

+ 3 - 0
service-dev/src/main/resources/application.yml

@@ -0,0 +1,3 @@
+spring:
+  profiles:
+    active: dev

+ 15 - 0
service-dev/src/main/resources/banner.txt

@@ -0,0 +1,15 @@
+${AnsiColor.BRIGHT_RED}
+     __                    ____ ___________
+    |__|____ ___  _______ /_   /_   \   _  \
+    |  \__  \\  \/ /\__  \ |   ||   /  /_\  \
+    |  |/ __ \\   /  / __ \|   ||   \  \_/   \
+/\__|  (____  /\_/  (____  /___||___|\_____  /
+\______|    \/           \/                \/
+ ____ ___                    _________                  .__
+|    |   \______ ___________/   _____/ ______________  _|__| ____  ____
+|    |   /  ___// __ \_  __ \_____  \_/ __ \_  __ \  \/ /  |/ ___\/ __ \
+|    |  /\___ \\  ___/|  | \/        \  ___/|  | \/\   /|  \  \__\  ___/
+|______//____  >\___  >__| /_______  /\___  >__|    \_/ |__|\___  >___  >
+             \/     \/             \/     \/                    \/    \/
+
+ java110 UserService starting, more information scan https://github.com/java110/MicroCommunity

+ 33 - 0
service-dev/src/main/resources/dataSource.yml

@@ -0,0 +1,33 @@
+dataSources:
+  ds0: !!com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://dev.db.java110.com:3306/TT?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
+    username: TT
+    password: TT@12345678
+    minIdle: 5
+    validationQuery: SELECT 1 FROM DUAL
+    initialSize: 5
+    maxWait: 60000
+    filters: stat,wall,log4j
+    poolPreparedStatements: true
+
+shardingRule:
+  tables:
+    business_xxx:
+      actualDataNodes: ds0.business_community
+      databaseStrategy:
+        inline:
+          shardingColumn: community_id
+          algorithmExpression: ds${Long.parseLong(community_id) % 2}
+
+  bindingTables:
+    - business_xxx
+
+  defaultDataSourceName: ds0
+  defaultDatabaseStrategy:
+    none:
+  defaultTableStrategy:
+    none:
+
+props:
+  sql.show: true

+ 3 - 0
service-dev/src/main/resources/java110.properties

@@ -0,0 +1,3 @@
+java110.mappingPath=classpath:mapper/dev/*.xml
+
+