├── common ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ │ └── java │ │ └── org │ │ └── bekit │ │ └── common │ │ ├── boot │ │ ├── CommonAutoConfiguration.java │ │ └── CommonConfiguration.java │ │ ├── transaction │ │ ├── support │ │ │ ├── EmptyTransactionManager.java │ │ │ └── SpringTransactionManager.java │ │ ├── TransactionManager.java │ │ └── TxExecutor.java │ │ ├── scanner │ │ └── AbstractScanner.java │ │ ├── method │ │ └── MethodExecutor.java │ │ ├── registrar │ │ └── AbstractRegistrar.java │ │ └── util │ │ └── EnumUtils.java └── pom.xml ├── event ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ │ └── java │ │ └── org │ │ └── bekit │ │ └── event │ │ ├── EventPublisher.java │ │ ├── extension │ │ ├── ListenerType.java │ │ ├── EventTypeResolver.java │ │ ├── support │ │ │ ├── DomainListenerType.java │ │ │ ├── ClassEventTypeResolver.java │ │ │ └── ClassListenResolver.java │ │ └── ListenResolver.java │ │ ├── listener │ │ ├── PriorityType.java │ │ ├── ListenerHub.java │ │ ├── ListenerExecutor.java │ │ └── ListenerParser.java │ │ ├── boot │ │ ├── EventBusAutoConfiguration.java │ │ └── EventBusConfiguration.java │ │ ├── annotation │ │ ├── listener │ │ │ ├── Listen.java │ │ │ └── Listener.java │ │ ├── DomainListener.java │ │ └── Listen.java │ │ ├── publisher │ │ └── DefaultEventPublisher.java │ │ └── bus │ │ ├── EventBusHub.java │ │ └── EventBus.java └── pom.xml ├── flow ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ │ └── java │ │ └── org │ │ └── bekit │ │ └── flow │ │ ├── flow │ │ ├── FlowRegistrar.java │ │ ├── FlowParser.java │ │ └── FlowExecutor.java │ │ ├── annotation │ │ ├── locker │ │ │ ├── FlowLock.java │ │ │ ├── FlowUnlock.java │ │ │ ├── StateLock.java │ │ │ ├── StateUnlock.java │ │ │ └── TheFlowLocker.java │ │ ├── processor │ │ │ ├── ProcessorExecute.java │ │ │ └── Processor.java │ │ ├── mapper │ │ │ ├── MappingNode.java │ │ │ └── TheFlowMapper.java │ │ ├── flow │ │ │ ├── Node.java │ │ │ ├── EndNode.java │ │ │ ├── PhaseNode.java │ │ │ ├── StartNode.java │ │ │ ├── TransientNode.java │ │ │ ├── PauseNode.java │ │ │ └── Flow.java │ │ └── listener │ │ │ ├── FlowListener.java │ │ │ ├── ListenFlowEnd.java │ │ │ ├── TheFlowListener.java │ │ │ ├── ListenFlowStart.java │ │ │ ├── ListenDecidedNode.java │ │ │ ├── ListenExecutingNode.java │ │ │ ├── ListenFlowException.java │ │ │ └── ListenDecidedStateNode.java │ │ ├── processor │ │ ├── ProcessorRegistrar.java │ │ ├── ProcessorExecutor.java │ │ └── ProcessorParser.java │ │ ├── locker │ │ ├── TheFlowLockerRegistrar.java │ │ ├── TheFlowLockerExecutor.java │ │ └── TheFlowLockerParser.java │ │ ├── mapper │ │ ├── TheFlowMapperRegistrar.java │ │ ├── TheFlowMapperExecutor.java │ │ └── TheFlowMapperParser.java │ │ ├── listener │ │ ├── FlowListenerType.java │ │ ├── TheFlowEventType.java │ │ ├── ListenFlowEndResolver.java │ │ ├── ListenFlowStartResolver.java │ │ ├── DefaultFlowListener.java │ │ ├── ListenDecidedNodeResolver.java │ │ ├── ListenExecutingNodeResolver.java │ │ ├── ListenFlowExceptionResolver.java │ │ ├── ListenDecidedStateNodeResolver.java │ │ └── TheFlowListenerType.java │ │ ├── event │ │ ├── FlowEndEvent.java │ │ ├── FlowStartEvent.java │ │ ├── DecidedNodeEvent.java │ │ ├── ExecutingNodeEvent.java │ │ ├── FlowExceptionEvent.java │ │ └── DecidedStateNodeEvent.java │ │ ├── boot │ │ ├── FlowEngineAutoConfiguration.java │ │ └── FlowEngineConfiguration.java │ │ ├── FlowEngine.java │ │ └── engine │ │ ├── FlowContext.java │ │ └── DefaultFlowEngine.java └── pom.xml ├── service ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── spring.factories │ │ └── java │ │ └── org │ │ └── bekit │ │ └── service │ │ ├── annotation │ │ ├── service │ │ │ ├── ServiceAfter.java │ │ │ ├── ServiceBefore.java │ │ │ ├── ServiceExecute.java │ │ │ └── Service.java │ │ └── listener │ │ │ └── ServiceListener.java │ │ ├── service │ │ ├── ServiceRegistrar.java │ │ ├── ServiceExecutor.java │ │ └── ServiceParser.java │ │ ├── engine │ │ ├── ServiceContext.java │ │ └── DefaultServiceEngine.java │ │ ├── listener │ │ └── ServiceListenerType.java │ │ ├── boot │ │ ├── ServiceEngineAutoConfiguration.java │ │ └── ServiceEngineConfiguration.java │ │ ├── event │ │ ├── ServiceApplyEvent.java │ │ ├── ServiceFinishEvent.java │ │ └── ServiceExceptionEvent.java │ │ └── ServiceEngine.java └── pom.xml ├── .gitignore ├── README.md ├── pom.xml └── LICENSE /common/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | org.bekit.common.boot.CommonAutoConfiguration -------------------------------------------------------------------------------- /event/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | org.bekit.event.boot.EventBusAutoConfiguration -------------------------------------------------------------------------------- /flow/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | org.bekit.flow.boot.FlowEngineAutoConfiguration 3 | -------------------------------------------------------------------------------- /service/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | org.bekit.service.boot.ServiceEngineAutoConfiguration -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # maven ignore 2 | target/ 3 | *.jar 4 | *.war 5 | *.zip 6 | *.tar 7 | *.tar.gz 8 | 9 | # eclipse ignore 10 | .settings/ 11 | .project 12 | .classpath 13 | 14 | # idea ignore 15 | .idea/ 16 | *.ipr 17 | *.iml 18 | *.iws 19 | 20 | # temp ignore 21 | *.log 22 | *.cache 23 | *.diff 24 | *.patch 25 | *.tmp 26 | 27 | # system ignore 28 | .DS_Store 29 | Thumbs.db 30 | 31 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/EventPublisher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event; 10 | 11 | /** 12 | * 事件发布器 13 | */ 14 | public interface EventPublisher { 15 | /** 16 | * 发布事件 17 | * 18 | * @param event 事件 19 | */ 20 | void publish(Object event); 21 | } 22 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/extension/ListenerType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 11:42 创建 8 | */ 9 | package org.bekit.event.extension; 10 | 11 | /** 12 | * 监听器类型(实现类需具有默认构造方法) 13 | */ 14 | public interface ListenerType { 15 | /** 16 | * 获取事件类型解决器 17 | */ 18 | EventTypeResolver getResolver(); 19 | } 20 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/extension/EventTypeResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 11:33 创建 8 | */ 9 | package org.bekit.event.extension; 10 | 11 | /** 12 | * 事件类型解决器 13 | */ 14 | public interface EventTypeResolver { 15 | /** 16 | * 根据事件得到对应的事件类型 17 | * 18 | * @param event 事件 19 | * @return 事件类型 20 | */ 21 | Object resolve(Object event); 22 | } 23 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/listener/PriorityType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-04 23:39 创建 8 | */ 9 | package org.bekit.event.listener; 10 | 11 | /** 12 | * 优先级类型(当一个事件发布时,总是先执行完优先级为升序的监听方法,再执行优先级为降序的监听方法) 13 | */ 14 | public enum PriorityType { 15 | /** 16 | * 升序(监听器中优先级值越小优先级越高) 17 | */ 18 | ASC, 19 | 20 | /** 21 | * 降序(监听器中优先级值越大优先级越高) 22 | */ 23 | DESC 24 | } 25 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/flow/FlowRegistrar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-19 01:26 创建 8 | */ 9 | package org.bekit.flow.flow; 10 | 11 | import org.bekit.common.registrar.AbstractRegistrar; 12 | 13 | /** 14 | * 流程注册器 15 | */ 16 | public class FlowRegistrar extends AbstractRegistrar { 17 | public FlowRegistrar() { 18 | super(FlowExecutor::getFlowName); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/locker/FlowLock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-15 22:25 创建 8 | */ 9 | package org.bekit.flow.annotation.locker; 10 | 11 | import java.lang.annotation.*; 12 | 13 | /** 14 | * 流程加锁 15 | *

16 | * 被标记的方法入参为FlowContext,返回值为加锁后的目标对象。 17 | */ 18 | @Target(ElementType.METHOD) 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Documented 21 | public @interface FlowLock { 22 | } 23 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/locker/FlowUnlock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-15 22:25 创建 8 | */ 9 | package org.bekit.flow.annotation.locker; 10 | 11 | import java.lang.annotation.*; 12 | 13 | /** 14 | * 流程解锁 15 | *

16 | * 被标记的方法入参为FlowContext,返回类型为void。 17 | */ 18 | @Target(ElementType.METHOD) 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Documented 21 | public @interface FlowUnlock { 22 | } 23 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/locker/StateLock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-15 22:25 创建 8 | */ 9 | package org.bekit.flow.annotation.locker; 10 | 11 | import java.lang.annotation.*; 12 | 13 | /** 14 | * 状态加锁 15 | *

16 | * 被标记的方法入参为FlowContext,返回值为加锁后的目标对象。 17 | */ 18 | @Target(ElementType.METHOD) 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Documented 21 | public @interface StateLock { 22 | } 23 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/locker/StateUnlock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-15 22:25 创建 8 | */ 9 | package org.bekit.flow.annotation.locker; 10 | 11 | import java.lang.annotation.*; 12 | 13 | /** 14 | * 状态解锁 15 | *

16 | * 被标记的方法入参为FlowContext,返回类型为void。 17 | */ 18 | @Target(ElementType.METHOD) 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Documented 21 | public @interface StateUnlock { 22 | } 23 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/annotation/service/ServiceAfter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-07 14:17 创建 8 | */ 9 | package org.bekit.service.annotation.service; 10 | 11 | import java.lang.annotation.*; 12 | 13 | /** 14 | * 服务后置处理(执行中不会有事务) 15 | */ 16 | @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Documented 19 | public @interface ServiceAfter { 20 | } 21 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/annotation/service/ServiceBefore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.annotation.service; 10 | 11 | import java.lang.annotation.*; 12 | 13 | /** 14 | * 服务前置处理(执行中不会有事务) 15 | */ 16 | @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Documented 19 | public @interface ServiceBefore { 20 | } 21 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/service/ServiceRegistrar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-25 23:41 创建 8 | */ 9 | package org.bekit.service.service; 10 | 11 | import org.bekit.common.registrar.AbstractRegistrar; 12 | 13 | /** 14 | * 服务注册器 15 | */ 16 | public class ServiceRegistrar extends AbstractRegistrar { 17 | public ServiceRegistrar() { 18 | super(ServiceExecutor::getServiceName); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/processor/ProcessorExecute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-17 17:46 创建 8 | */ 9 | package org.bekit.flow.annotation.processor; 10 | 11 | import java.lang.annotation.*; 12 | 13 | /** 14 | * 处理器执行 15 | *

16 | * 被标记的方法入参为FlowContext,返回值作为整个处理器的返回值并返回给流程节点。 17 | */ 18 | @Documented 19 | @Target(ElementType.METHOD) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | public @interface ProcessorExecute { 22 | } 23 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/processor/ProcessorRegistrar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-18 14:41 创建 8 | */ 9 | package org.bekit.flow.processor; 10 | 11 | import org.bekit.common.registrar.AbstractRegistrar; 12 | 13 | /** 14 | * 处理器注册器 15 | */ 16 | public class ProcessorRegistrar extends AbstractRegistrar { 17 | public ProcessorRegistrar() { 18 | super(ProcessorExecutor::getProcessorName); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/locker/TheFlowLockerRegistrar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-22 19:19 创建 8 | */ 9 | package org.bekit.flow.locker; 10 | 11 | import org.bekit.common.registrar.AbstractRegistrar; 12 | 13 | /** 14 | * 特定流程加锁器注册器 15 | */ 16 | public class TheFlowLockerRegistrar extends AbstractRegistrar { 17 | public TheFlowLockerRegistrar() { 18 | super(TheFlowLockerExecutor::getFlow); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/mapper/TheFlowMapperRegistrar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-22 17:45 创建 8 | */ 9 | package org.bekit.flow.mapper; 10 | 11 | import org.bekit.common.registrar.AbstractRegistrar; 12 | 13 | /** 14 | * 特定流程映射器注册器 15 | */ 16 | public class TheFlowMapperRegistrar extends AbstractRegistrar { 17 | public TheFlowMapperRegistrar() { 18 | super(TheFlowMapperExecutor::getFlow); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/mapper/MappingNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-28 20:59 创建 8 | */ 9 | package org.bekit.flow.annotation.mapper; 10 | 11 | import java.lang.annotation.*; 12 | 13 | /** 14 | * 映射出节点 15 | *

16 | * 流程刚开始执行以及流程加锁器每次加锁后都会调用映射出节点,映射出接下来要执行的节点。 17 | * 被标记的方法入参为FlowContext,返回类型值为要执行的节点 18 | */ 19 | @Target(ElementType.METHOD) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Documented 22 | public @interface MappingNode { 23 | } 24 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/annotation/service/ServiceExecute.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.annotation.service; 10 | 11 | import java.lang.annotation.*; 12 | 13 | /** 14 | * 服务执行(如果@Service的enableTx属性为true,则在执行前会开启新事务;如果本注解标注的方法无异常抛出,则会提交事务,否则会回滚事务) 15 | */ 16 | @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Documented 19 | public @interface ServiceExecute { 20 | } 21 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/locker/TheFlowLocker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-15 22:19 创建 8 | */ 9 | package org.bekit.flow.annotation.locker; 10 | 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.lang.annotation.*; 14 | 15 | /** 16 | * 特定流程加锁器 17 | */ 18 | @Target(ElementType.TYPE) 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Documented 21 | @Component 22 | public @interface TheFlowLocker { 23 | /** 24 | * 加锁的流程 25 | */ 26 | String flow(); 27 | } 28 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/mapper/TheFlowMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-15 22:19 创建 8 | */ 9 | package org.bekit.flow.annotation.mapper; 10 | 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.lang.annotation.*; 14 | 15 | /** 16 | * 特定流程映射器 17 | */ 18 | @Target(ElementType.TYPE) 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Documented 21 | @Component 22 | public @interface TheFlowMapper { 23 | /** 24 | * 映射的流程 25 | */ 26 | String flow(); 27 | } 28 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/extension/support/DomainListenerType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 12:41 创建 8 | */ 9 | package org.bekit.event.extension.support; 10 | 11 | import org.bekit.event.extension.EventTypeResolver; 12 | import org.bekit.event.extension.ListenerType; 13 | 14 | /** 15 | * 领域监听器类型 16 | */ 17 | public class DomainListenerType implements ListenerType { 18 | @Override 19 | public EventTypeResolver getResolver() { 20 | return ClassEventTypeResolver.INSTANCE; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/processor/Processor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-14 21:44 创建 8 | */ 9 | 10 | package org.bekit.flow.annotation.processor; 11 | 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.lang.annotation.*; 15 | 16 | /** 17 | * 处理器 18 | */ 19 | @Target(ElementType.TYPE) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Documented 22 | @Component 23 | public @interface Processor { 24 | /** 25 | * 处理器名字(默认使用被注解的类名且首字母小写) 26 | */ 27 | String name() default ""; 28 | } 29 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/engine/ServiceContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.engine; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | 14 | import java.util.Map; 15 | 16 | /** 17 | * 服务上下文 18 | */ 19 | @AllArgsConstructor 20 | @Getter 21 | public class ServiceContext { 22 | // 入参 23 | private final O order; 24 | // 结果 25 | private final R result; 26 | // 附件(可往里面设值,可传递一些附加信息) 27 | private final Map attachment; 28 | } 29 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/listener/FlowListenerType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 19:46 创建 8 | */ 9 | package org.bekit.flow.listener; 10 | 11 | import org.bekit.event.extension.EventTypeResolver; 12 | import org.bekit.event.extension.ListenerType; 13 | import org.bekit.event.extension.support.ClassEventTypeResolver; 14 | 15 | /** 16 | * 流程监听器类型 17 | */ 18 | public class FlowListenerType implements ListenerType { 19 | @Override 20 | public EventTypeResolver getResolver() { 21 | return ClassEventTypeResolver.INSTANCE; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/listener/ServiceListenerType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 23:11 创建 8 | */ 9 | package org.bekit.service.listener; 10 | 11 | import org.bekit.event.extension.EventTypeResolver; 12 | import org.bekit.event.extension.ListenerType; 13 | import org.bekit.event.extension.support.ClassEventTypeResolver; 14 | 15 | /** 16 | * 服务监听器类型 17 | */ 18 | public class ServiceListenerType implements ListenerType { 19 | @Override 20 | public EventTypeResolver getResolver() { 21 | return ClassEventTypeResolver.INSTANCE; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/event/FlowEndEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 20:21 创建 8 | */ 9 | package org.bekit.flow.event; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.flow.engine.FlowContext; 14 | 15 | /** 16 | * 流程结束事件 17 | */ 18 | @AllArgsConstructor 19 | public class FlowEndEvent { 20 | // 流程名称 21 | @Getter 22 | private final String flow; 23 | // 流程上下文 24 | private final FlowContext context; 25 | 26 | public FlowContext getContext() { 27 | return (FlowContext) context; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/event/FlowStartEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 20:21 创建 8 | */ 9 | package org.bekit.flow.event; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.flow.engine.FlowContext; 14 | 15 | /** 16 | * 流程开始事件 17 | */ 18 | @AllArgsConstructor 19 | public class FlowStartEvent { 20 | // 流程名称 21 | @Getter 22 | private final String flow; 23 | // 流程上下文 24 | private final FlowContext context; 25 | 26 | public FlowContext getContext() { 27 | return (FlowContext) context; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/boot/EventBusAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event.boot; 10 | 11 | import org.bekit.common.boot.CommonAutoConfiguration; 12 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.context.annotation.Import; 15 | 16 | /** 17 | * 事件总线自动配置 18 | */ 19 | @Configuration 20 | @AutoConfigureAfter(CommonAutoConfiguration.class) 21 | @Import(EventBusConfiguration.class) 22 | public class EventBusAutoConfiguration { 23 | } 24 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/boot/FlowEngineAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-23 00:36 创建 8 | */ 9 | package org.bekit.flow.boot; 10 | 11 | import org.bekit.event.boot.EventBusAutoConfiguration; 12 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.context.annotation.Import; 15 | 16 | /** 17 | * 流程引擎自动配置 18 | */ 19 | @Configuration 20 | @AutoConfigureAfter(EventBusAutoConfiguration.class) 21 | @Import(FlowEngineConfiguration.class) 22 | public class FlowEngineAutoConfiguration { 23 | } 24 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/extension/support/ClassEventTypeResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 11:51 创建 8 | */ 9 | package org.bekit.event.extension.support; 10 | 11 | import org.bekit.event.extension.EventTypeResolver; 12 | 13 | /** 14 | * Class事件类型解决器(事件类型就是事件对应的Class类) 15 | */ 16 | public class ClassEventTypeResolver implements EventTypeResolver { 17 | /** 18 | * 实例 19 | */ 20 | public static final ClassEventTypeResolver INSTANCE = new ClassEventTypeResolver(); 21 | 22 | @Override 23 | public Object resolve(Object event) { 24 | return event.getClass(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/boot/ServiceEngineAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.boot; 10 | 11 | import org.bekit.event.boot.EventBusAutoConfiguration; 12 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.context.annotation.Import; 15 | 16 | /** 17 | * 服务引擎自动配置 18 | */ 19 | @Configuration 20 | @AutoConfigureAfter(EventBusAutoConfiguration.class) 21 | @Import(ServiceEngineConfiguration.class) 22 | public class ServiceEngineAutoConfiguration { 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/org/bekit/common/boot/CommonAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-02 20:37 创建 8 | */ 9 | package org.bekit.common.boot; 10 | 11 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 12 | import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.context.annotation.Import; 15 | 16 | /** 17 | * 公共自动配置 18 | */ 19 | @Configuration 20 | @AutoConfigureAfter(TransactionAutoConfiguration.class) 21 | @Import(CommonConfiguration.class) 22 | public class CommonAutoConfiguration { 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/org/bekit/common/transaction/support/EmptyTransactionManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-02 19:27 创建 8 | */ 9 | package org.bekit.common.transaction.support; 10 | 11 | import org.bekit.common.transaction.TransactionManager; 12 | 13 | /** 14 | * 空事务管理器 15 | */ 16 | public class EmptyTransactionManager implements TransactionManager { 17 | @Override 18 | public Object getTransaction(TransactionType type) { 19 | return new Object(); 20 | } 21 | 22 | @Override 23 | public void commit(Object status) { 24 | } 25 | 26 | @Override 27 | public void rollback(Object status) { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/event/ServiceApplyEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.event; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.service.engine.ServiceContext; 14 | 15 | /** 16 | * 服务申请事件 17 | */ 18 | @AllArgsConstructor 19 | public class ServiceApplyEvent { 20 | // 服务名称 21 | @Getter 22 | private final String service; 23 | // 服务上下文 24 | private final ServiceContext context; 25 | 26 | public ServiceContext getContext() { 27 | return (ServiceContext) context; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/event/ServiceFinishEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.event; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.service.engine.ServiceContext; 14 | 15 | /** 16 | * 服务完成事件 17 | */ 18 | @AllArgsConstructor 19 | public class ServiceFinishEvent { 20 | // 服务名称 21 | @Getter 22 | private final String service; 23 | // 服务上下文 24 | private final ServiceContext context; 25 | 26 | public ServiceContext getContext() { 27 | return (ServiceContext) context; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/annotation/listener/Listen.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event.annotation.listener; 10 | 11 | import org.bekit.event.extension.ListenResolver; 12 | import org.bekit.event.listener.PriorityType; 13 | 14 | import java.lang.annotation.*; 15 | 16 | /** 17 | * 监听 18 | */ 19 | @Target(ElementType.ANNOTATION_TYPE) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Documented 22 | public @interface Listen { 23 | /** 24 | * 监听解决器 25 | */ 26 | Class resolver(); 27 | 28 | /** 29 | * 优先级类型 30 | */ 31 | PriorityType priorityType(); 32 | } 33 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/annotation/listener/Listener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event.annotation.listener; 10 | 11 | import org.bekit.event.extension.ListenerType; 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.lang.annotation.*; 15 | 16 | /** 17 | * 监听器 18 | */ 19 | @Target(ElementType.ANNOTATION_TYPE) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Documented 22 | @Component 23 | public @interface Listener { 24 | /** 25 | * 类型 26 | */ 27 | Class type(); 28 | 29 | /** 30 | * 优先级 31 | */ 32 | int priority(); 33 | } 34 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/flow/Node.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-14 21:35 创建 8 | */ 9 | package org.bekit.flow.annotation.flow; 10 | 11 | import java.lang.annotation.*; 12 | 13 | /** 14 | * 节点 15 | */ 16 | @Target(ElementType.ANNOTATION_TYPE) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Documented 19 | public @interface Node { 20 | /** 21 | * 节点名称 22 | */ 23 | String name(); 24 | 25 | /** 26 | * 是否有状态 27 | */ 28 | boolean haveState(); 29 | 30 | /** 31 | * 是否自动执行 32 | */ 33 | boolean autoExecute(); 34 | 35 | /** 36 | * 处理器 37 | */ 38 | String processor(); 39 | } 40 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/event/DecidedNodeEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 20:16 创建 8 | */ 9 | package org.bekit.flow.event; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.flow.engine.FlowContext; 14 | 15 | /** 16 | * 节点选择事件 17 | */ 18 | @AllArgsConstructor 19 | public class DecidedNodeEvent { 20 | // 流程名称 21 | @Getter 22 | private final String flow; 23 | // 被选择的节点 24 | @Getter 25 | private final String node; 26 | // 流程上下文 27 | private final FlowContext context; 28 | 29 | public FlowContext getContext() { 30 | return (FlowContext) context; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/extension/ListenResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 11:35 创建 8 | */ 9 | package org.bekit.event.extension; 10 | 11 | import java.lang.reflect.Method; 12 | 13 | /** 14 | * 监听解决器(实现类需具有默认构造方法) 15 | */ 16 | public interface ListenResolver { 17 | /** 18 | * 初始化(每个实例仅调用一次) 19 | * 20 | * @param listenMethod 监听方法 21 | */ 22 | void init(Method listenMethod); 23 | 24 | /** 25 | * 获取监听的事件类型 26 | */ 27 | Object getEventType(); 28 | 29 | /** 30 | * 解决调用监听方法的入参 31 | * 32 | * @param event 事件 33 | * @return 调用监听方法的入参 34 | */ 35 | Object[] resolveParams(Object event); 36 | } 37 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/event/ExecutingNodeEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 20:16 创建 8 | */ 9 | package org.bekit.flow.event; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.flow.engine.FlowContext; 14 | 15 | /** 16 | * 正在执行的节点事件 17 | */ 18 | @AllArgsConstructor 19 | public class ExecutingNodeEvent { 20 | // 流程名称 21 | @Getter 22 | private final String flow; 23 | // 正在执行的节点 24 | @Getter 25 | private final String node; 26 | // 流程上下文 27 | private final FlowContext context; 28 | 29 | public FlowContext getContext() { 30 | return (FlowContext) context; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/event/FlowExceptionEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 20:21 创建 8 | */ 9 | package org.bekit.flow.event; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.flow.engine.FlowContext; 14 | 15 | /** 16 | * 流程异常事件 17 | */ 18 | @AllArgsConstructor 19 | public class FlowExceptionEvent { 20 | // 流程名称 21 | @Getter 22 | private final String flow; 23 | // 发生的异常 24 | @Getter 25 | private final Throwable throwable; 26 | // 流程上下文 27 | private final FlowContext context; 28 | 29 | public FlowContext getContext() { 30 | return (FlowContext) context; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/event/DecidedStateNodeEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 20:16 创建 8 | */ 9 | package org.bekit.flow.event; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.flow.engine.FlowContext; 14 | 15 | /** 16 | * 状态节点选择事件 17 | */ 18 | @AllArgsConstructor 19 | public class DecidedStateNodeEvent { 20 | // 流程名称 21 | @Getter 22 | private final String flow; 23 | // 被选择的状态节点 24 | @Getter 25 | private final String node; 26 | // 流程上下文 27 | private final FlowContext context; 28 | 29 | public FlowContext getContext() { 30 | return (FlowContext) context; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 简介 2 | bekit框架致力于解决在应用开发中公共性问题,目前已完成“事件总线”、“流程引擎”、“服务引擎”功能模块。 3 | > 环境要求 4 | > * jdk1.8 5 | > * Spring 4.2及以上 6 | 7 | > 注意:本框架已经上传到[maven中央库](https://search.maven.org/#search%7Cga%7C1%7Corg.bekit) 8 | 9 | # 文档 10 | * [事件总线](https://github.com/zhongxunking/bekit/wiki/%E4%BA%8B%E4%BB%B6%E6%80%BB%E7%BA%BF) 11 | * [流程引擎](https://github.com/zhongxunking/bekit/wiki/%E6%B5%81%E7%A8%8B%E5%BC%95%E6%93%8E) 12 | * [服务引擎](https://github.com/zhongxunking/bekit/wiki/%E6%9C%8D%E5%8A%A1%E5%BC%95%E6%93%8E) 13 | 14 | # 示例 15 | 结合示例看文档会更容易上手:https://github.com/zhongxunking/bekit-demo 16 | 17 | # 技术支持 18 | 欢迎加我微信(zhong_xun_)入群交流。
19 | 20 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/event/ServiceExceptionEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.event; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.service.engine.ServiceContext; 14 | 15 | /** 16 | * 服务异常事件 17 | */ 18 | @AllArgsConstructor 19 | public class ServiceExceptionEvent { 20 | // 服务名称 21 | @Getter 22 | private final String service; 23 | // 发生的异常 24 | @Getter 25 | private final Throwable throwable; 26 | // 服务上下文 27 | private final ServiceContext context; 28 | 29 | public ServiceContext getContext() { 30 | return (ServiceContext) context; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/FlowEngine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-17 19:06 创建 8 | */ 9 | package org.bekit.flow; 10 | 11 | import java.util.Map; 12 | 13 | /** 14 | * 流程引擎 15 | */ 16 | public interface FlowEngine { 17 | /** 18 | * 执行流程 19 | * 20 | * @param flow 流程名称 21 | * @param target 目标对象 22 | * @return 流程执行结束后的目标对象(可能和传入的目标对象不是同一个对象) 23 | */ 24 | T execute(String flow, T target); 25 | 26 | /** 27 | * 执行流程 28 | * 29 | * @param flow 流程名称 30 | * @param target 目标对象 31 | * @param attachment 附件 32 | * @return 流程执行结束后的目标对象(可能和传入的目标对象不是同一个对象) 33 | */ 34 | T execute(String flow, T target, Map attachment); 35 | } 36 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/flow/EndNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.flow.annotation.flow; 10 | 11 | import org.springframework.core.annotation.AliasFor; 12 | 13 | import java.lang.annotation.*; 14 | 15 | /** 16 | * 结束节点 17 | *

18 | * 结束节点是流程结束的标志。当流程跳转到结束节点时,流程会自动结束。 19 | * 对应的节点决策器返回类型必须是void,且不能有入参。节点决策器的方法体不会被执行。 20 | */ 21 | @Target(ElementType.METHOD) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | @Documented 24 | @Node(name = "", haveState = true, autoExecute = false, processor = "") 25 | public @interface EndNode { 26 | /** 27 | * 节点名称(默认使用被注解的函数名) 28 | */ 29 | @AliasFor(annotation = Node.class, attribute = "name") 30 | String name() default ""; 31 | } 32 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/publisher/DefaultEventPublisher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event.publisher; 10 | 11 | import lombok.AllArgsConstructor; 12 | import org.apache.commons.lang3.exception.ExceptionUtils; 13 | import org.bekit.event.EventPublisher; 14 | import org.bekit.event.bus.EventBus; 15 | 16 | /** 17 | * 事件发布器的默认实现 18 | */ 19 | @AllArgsConstructor 20 | public class DefaultEventPublisher implements EventPublisher { 21 | // 事件总线 22 | private final EventBus eventBus; 23 | 24 | @Override 25 | public void publish(Object event) { 26 | try { 27 | eventBus.dispatch(event); 28 | } catch (Throwable e) { 29 | ExceptionUtils.rethrow(e); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/engine/FlowContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-18 12:14 创建 8 | */ 9 | package org.bekit.flow.engine; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.springframework.util.Assert; 14 | 15 | import java.util.Map; 16 | 17 | /** 18 | * 流程上下文 19 | */ 20 | @AllArgsConstructor 21 | @Getter 22 | public class FlowContext { 23 | // 目标对象 24 | private T target; 25 | // 附件(可往里面设值,可传递一些附加信息) 26 | private final Map attachment; 27 | 28 | /** 29 | * 刷新目标对象 30 | * 31 | * @param newTarget 新的目标对象 32 | */ 33 | public void refreshTarget(T newTarget) { 34 | Assert.notNull(newTarget, "目标对象不能为null"); 35 | this.target = newTarget; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/annotation/DomainListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event.annotation; 10 | 11 | import org.bekit.event.annotation.listener.Listener; 12 | import org.bekit.event.extension.support.DomainListenerType; 13 | import org.springframework.core.annotation.AliasFor; 14 | 15 | import java.lang.annotation.*; 16 | 17 | /** 18 | * 领域监听器 19 | */ 20 | @Target(ElementType.TYPE) 21 | @Retention(RetentionPolicy.RUNTIME) 22 | @Documented 23 | @Listener(type = DomainListenerType.class, priority = Integer.MAX_VALUE) 24 | public @interface DomainListener { 25 | /** 26 | * 优先级 27 | */ 28 | @AliasFor(annotation = Listener.class, attribute = "priority") 29 | int priority() default Integer.MAX_VALUE; 30 | } 31 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/listener/FlowListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 20:45 创建 8 | */ 9 | package org.bekit.flow.annotation.listener; 10 | 11 | import org.bekit.event.annotation.listener.Listener; 12 | import org.bekit.flow.listener.FlowListenerType; 13 | import org.springframework.core.annotation.AliasFor; 14 | 15 | import java.lang.annotation.*; 16 | 17 | /** 18 | * 流程监听器(监听所有流程发生的事件) 19 | */ 20 | @Target(ElementType.TYPE) 21 | @Retention(RetentionPolicy.RUNTIME) 22 | @Documented 23 | @Listener(type = FlowListenerType.class, priority = Integer.MAX_VALUE) 24 | public @interface FlowListener { 25 | /** 26 | * 优先级 27 | */ 28 | @AliasFor(annotation = Listener.class, attribute = "priority") 29 | int priority() default Integer.MAX_VALUE; 30 | } 31 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/annotation/listener/ServiceListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.annotation.listener; 10 | 11 | import org.bekit.event.annotation.listener.Listener; 12 | import org.bekit.service.listener.ServiceListenerType; 13 | import org.springframework.core.annotation.AliasFor; 14 | 15 | import java.lang.annotation.*; 16 | 17 | /** 18 | * 服务监听器 19 | */ 20 | @Target(ElementType.TYPE) 21 | @Retention(RetentionPolicy.RUNTIME) 22 | @Documented 23 | @Listener(type = ServiceListenerType.class, priority = Integer.MAX_VALUE) 24 | public @interface ServiceListener { 25 | /** 26 | * 优先级 27 | */ 28 | @AliasFor(annotation = Listener.class, attribute = "priority") 29 | int priority() default Integer.MAX_VALUE; 30 | } 31 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/annotation/service/Service.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.annotation.service; 10 | 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.lang.annotation.*; 14 | 15 | /** 16 | * 服务 17 | *

18 | * 执行顺序:@ServiceBefore(如果存在)、@ServiceExecute、@ServiceAfter(如果存在) 19 | * 如果enableTx为true,则在执行@ServiceExecute前先开启融合事务,如果@ServiceExecute标注的方法无异常抛出,则会提交事务,否则会回滚事务 20 | */ 21 | @Target(ElementType.TYPE) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | @Documented 24 | @Component 25 | public @interface Service { 26 | /** 27 | * 服务名称(默认使用被注解的类名,首字母小写) 28 | */ 29 | String name() default ""; 30 | 31 | /** 32 | * 是否开启事务(默认关闭) 33 | */ 34 | boolean enableTx() default false; 35 | } 36 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/ServiceEngine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service; 10 | 11 | import java.util.Map; 12 | 13 | /** 14 | * 服务引擎 15 | */ 16 | public interface ServiceEngine { 17 | /** 18 | * 执行服务 19 | * 20 | * @param service 服务名称 21 | * @param order 入参 22 | * @param 入参类型 23 | * @param 出参类型 24 | * @return 出参 25 | */ 26 | R execute(String service, O order); 27 | 28 | /** 29 | * 执行服务 30 | * 31 | * @param service 服务名称 32 | * @param order 入参 33 | * @param attachment 附件 34 | * @param 入参类型 35 | * @param 出参类型 36 | * @return 出参 37 | */ 38 | R execute(String service, O order, Map attachment); 39 | } 40 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/annotation/Listen.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 12:53 创建 8 | */ 9 | package org.bekit.event.annotation; 10 | 11 | import org.bekit.event.extension.support.ClassListenResolver; 12 | import org.bekit.event.listener.PriorityType; 13 | import org.springframework.core.annotation.AliasFor; 14 | 15 | import java.lang.annotation.*; 16 | 17 | /** 18 | * 监听 19 | */ 20 | @Target(ElementType.METHOD) 21 | @Retention(RetentionPolicy.RUNTIME) 22 | @Documented 23 | @org.bekit.event.annotation.listener.Listen(resolver = ClassListenResolver.class, priorityType = PriorityType.ASC) 24 | public @interface Listen { 25 | /** 26 | * 优先级类型(默认为升序) 27 | */ 28 | @AliasFor(annotation = org.bekit.event.annotation.listener.Listen.class, attribute = "priorityType") 29 | PriorityType priorityType() default PriorityType.ASC; 30 | } 31 | -------------------------------------------------------------------------------- /common/src/main/java/org/bekit/common/transaction/TransactionManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-01 22:02 创建 8 | */ 9 | package org.bekit.common.transaction; 10 | 11 | /** 12 | * 事务管理器 13 | */ 14 | public interface TransactionManager { 15 | /** 16 | * 获取事务 17 | * 18 | * @param type 事务类型 19 | * @return 事务状态(非null) 20 | */ 21 | Object getTransaction(TransactionType type); 22 | 23 | /** 24 | * 提交 25 | * 26 | * @param status 事务状态 27 | */ 28 | void commit(Object status); 29 | 30 | /** 31 | * 回滚 32 | * 33 | * @param status 事务状态 34 | */ 35 | void rollback(Object status); 36 | 37 | /** 38 | * 事务类型 39 | */ 40 | enum TransactionType { 41 | // 融合事务(如果已存在事务,则使用已存在事务;否则创建新事务) 42 | REQUIRED, 43 | // 新事务(不管是否已存在事务,都创建新事务) 44 | REQUIRES_NEW, 45 | // 无事务(如果已存在事务,则挂起已存在事务;否则不做处理) 46 | NOT_SUPPORTED 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/flow/PhaseNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:38 创建 8 | */ 9 | package org.bekit.flow.annotation.flow; 10 | 11 | import org.springframework.core.annotation.AliasFor; 12 | 13 | import java.lang.annotation.*; 14 | 15 | /** 16 | * 阶段节点 17 | *

18 | * 阶段节点是一个阶段开始的标志。流程跳转到阶段节点时,会继续执行。 19 | * 对应的节点决策器返回值类型必须为String,入参类型可为:()、(FlowContext)、(T)、(T, FlowContext)————T表示能被对应的处理器返回结果赋值的类型。 20 | */ 21 | @Target(ElementType.METHOD) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | @Documented 24 | @Node(name = "", haveState = true, autoExecute = true, processor = "") 25 | public @interface PhaseNode { 26 | /** 27 | * 节点名称(默认使用被注解的函数名) 28 | */ 29 | @AliasFor(annotation = Node.class, attribute = "name") 30 | String name() default ""; 31 | 32 | /** 33 | * 节点处理器(默认不执行处理器) 34 | */ 35 | @AliasFor(annotation = Node.class, attribute = "processor") 36 | String processor() default ""; 37 | } 38 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/flow/StartNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-15 23:41 创建 8 | */ 9 | package org.bekit.flow.annotation.flow; 10 | 11 | import org.springframework.core.annotation.AliasFor; 12 | 13 | import java.lang.annotation.*; 14 | 15 | /** 16 | * 开始节点 17 | *

18 | * 开始节点是一个流程最开始执行的节点,流程必须有一个唯一的开始节点。 19 | * 对应的节点决策器返回值类型必须为String,入参类型可为:()、(FlowContext)、(T)、(T, FlowContext)————T表示能被对应的处理器返回结果赋值的类型。 20 | */ 21 | @Target(ElementType.METHOD) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | @Documented 24 | @Node(name = "", haveState = true, autoExecute = true, processor = "") 25 | public @interface StartNode { 26 | /** 27 | * 节点名称(默认使用被注解的函数名) 28 | */ 29 | @AliasFor(annotation = Node.class, attribute = "name") 30 | String name() default ""; 31 | 32 | /** 33 | * 节点处理器(默认不执行处理器) 34 | */ 35 | @AliasFor(annotation = Node.class, attribute = "processor") 36 | String processor() default ""; 37 | } 38 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/flow/TransientNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:34 创建 8 | */ 9 | package org.bekit.flow.annotation.flow; 10 | 11 | import org.springframework.core.annotation.AliasFor; 12 | 13 | import java.lang.annotation.*; 14 | 15 | /** 16 | * 瞬态节点 17 | *

18 | * 瞬态节点是一种单纯的处理单元,执行前不会提交和新建事务。 19 | * 对应的节点决策器返回值类型必须为String,入参类型可为:()、(FlowContext)、(T)、(T, FlowContext)————T表示能被对应的处理器返回结果赋值的类型。 20 | */ 21 | @Target(ElementType.METHOD) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | @Documented 24 | @Node(name = "", haveState = false, autoExecute = true, processor = "") 25 | public @interface TransientNode { 26 | /** 27 | * 节点名称(默认使用被注解的函数名) 28 | */ 29 | @AliasFor(annotation = Node.class, attribute = "name") 30 | String name() default ""; 31 | 32 | /** 33 | * 节点处理器(默认不执行处理器) 34 | */ 35 | @AliasFor(annotation = Node.class, attribute = "processor") 36 | String processor() default ""; 37 | } 38 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/listener/ListenFlowEnd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 18:41 创建 8 | */ 9 | package org.bekit.flow.annotation.listener; 10 | 11 | import org.bekit.event.annotation.listener.Listen; 12 | import org.bekit.event.listener.PriorityType; 13 | import org.bekit.flow.listener.ListenFlowEndResolver; 14 | import org.springframework.core.annotation.AliasFor; 15 | 16 | import java.lang.annotation.*; 17 | 18 | /** 19 | * 监听流程结束事件 20 | *

21 | * 配合@TheFlowListener一起使用;当流程执行结束时,都会调用本注解标注的方法。 22 | * 对应的方法入参类型必须为(FlowContext)。 23 | */ 24 | @Target(ElementType.METHOD) 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Documented 27 | @Listen(resolver = ListenFlowEndResolver.class, priorityType = PriorityType.ASC) 28 | public @interface ListenFlowEnd { 29 | /** 30 | * 优先级类型(默认为升序) 31 | */ 32 | @AliasFor(annotation = Listen.class, attribute = "priorityType") 33 | PriorityType priorityType() default PriorityType.ASC; 34 | } 35 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/listener/TheFlowListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 16:19 创建 8 | */ 9 | package org.bekit.flow.annotation.listener; 10 | 11 | import org.bekit.event.annotation.listener.Listener; 12 | import org.bekit.flow.listener.TheFlowListenerType; 13 | import org.springframework.core.annotation.AliasFor; 14 | 15 | import java.lang.annotation.*; 16 | 17 | /** 18 | * 特定流程监听器 19 | *

20 | * 监听某一个特定流程发生的事件,配合@ListenDecidedNode、@ListenDecidedStateNode、@ListenFlowException一起使用。 21 | */ 22 | @Target(ElementType.TYPE) 23 | @Retention(RetentionPolicy.RUNTIME) 24 | @Documented 25 | @Listener(type = TheFlowListenerType.class, priority = Integer.MAX_VALUE) 26 | public @interface TheFlowListener { 27 | /** 28 | * 监听的流程 29 | */ 30 | String flow(); 31 | 32 | /** 33 | * 优先级 34 | */ 35 | @AliasFor(annotation = Listener.class, attribute = "priority") 36 | int priority() default Integer.MAX_VALUE; 37 | } 38 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/listener/ListenFlowStart.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 18:41 创建 8 | */ 9 | package org.bekit.flow.annotation.listener; 10 | 11 | import org.bekit.event.annotation.listener.Listen; 12 | import org.bekit.event.listener.PriorityType; 13 | import org.bekit.flow.listener.ListenFlowStartResolver; 14 | import org.springframework.core.annotation.AliasFor; 15 | 16 | import java.lang.annotation.*; 17 | 18 | /** 19 | * 监听流程开始事件 20 | *

21 | * 配合@TheFlowListener一起使用;当流程开始执行时,都会调用本注解标注的方法。 22 | * 对应的方法入参类型必须为(FlowContext)。 23 | */ 24 | @Target(ElementType.METHOD) 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Documented 27 | @Listen(resolver = ListenFlowStartResolver.class, priorityType = PriorityType.ASC) 28 | public @interface ListenFlowStart { 29 | /** 30 | * 优先级类型(默认为升序) 31 | */ 32 | @AliasFor(annotation = Listen.class, attribute = "priorityType") 33 | PriorityType priorityType() default PriorityType.ASC; 34 | } 35 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/flow/PauseNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-15 23:36 创建 8 | */ 9 | package org.bekit.flow.annotation.flow; 10 | 11 | import org.springframework.core.annotation.AliasFor; 12 | 13 | import java.lang.annotation.*; 14 | 15 | /** 16 | * 暂停节点 17 | *

18 | * 暂停节点是正常中断流程的节点。流程跳转到暂停节点时,会正常中断;暂停节点只有是第一个被执行的节点时,流程才会继续执行。 19 | * 对应的节点决策器返回值类型必须为String,入参类型可为:()、(FlowContext)、(T)、(T, FlowContext)————T表示能被对应的处理器返回结果赋值的类型。 20 | */ 21 | @Target(ElementType.METHOD) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | @Documented 24 | @Node(name = "", haveState = true, autoExecute = false, processor = "") 25 | public @interface PauseNode { 26 | /** 27 | * 节点名称(默认使用被注解的函数名) 28 | */ 29 | @AliasFor(annotation = Node.class, attribute = "name") 30 | String name() default ""; 31 | 32 | /** 33 | * 节点处理器(默认不执行处理器) 34 | */ 35 | @AliasFor(annotation = Node.class, attribute = "processor") 36 | String processor() default ""; 37 | } 38 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/listener/ListenDecidedNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-17 17:06 创建 8 | */ 9 | package org.bekit.flow.annotation.listener; 10 | 11 | import org.bekit.event.annotation.listener.Listen; 12 | import org.bekit.event.listener.PriorityType; 13 | import org.bekit.flow.listener.ListenDecidedNodeResolver; 14 | import org.springframework.core.annotation.AliasFor; 15 | 16 | import java.lang.annotation.*; 17 | 18 | /** 19 | * 监听被选择的节点 20 | *

21 | * 配合@TheFlowListener一起使用;当每次节点决策器选择下一个节点时,都会调用本注解标注的方法。 22 | * 对应的方法入参类型必须为(String, FlowContext)。 23 | */ 24 | @Target(ElementType.METHOD) 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Documented 27 | @Listen(resolver = ListenDecidedNodeResolver.class, priorityType = PriorityType.ASC) 28 | public @interface ListenDecidedNode { 29 | /** 30 | * 优先级类型(默认为升序) 31 | */ 32 | @AliasFor(annotation = Listen.class, attribute = "priorityType") 33 | PriorityType priorityType() default PriorityType.ASC; 34 | } 35 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/listener/ListenExecutingNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-17 17:06 创建 8 | */ 9 | package org.bekit.flow.annotation.listener; 10 | 11 | import org.bekit.event.annotation.listener.Listen; 12 | import org.bekit.event.listener.PriorityType; 13 | import org.bekit.flow.listener.ListenExecutingNodeResolver; 14 | import org.springframework.core.annotation.AliasFor; 15 | 16 | import java.lang.annotation.*; 17 | 18 | /** 19 | * 监听正在执行的节点 20 | *

21 | * 配合@TheFlowListener一起使用;当每次节点即将被执行时,都会调用本注解标注的方法。 22 | * 对应的方法入参类型必须为(String, FlowContext)。 23 | */ 24 | @Target(ElementType.METHOD) 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Documented 27 | @Listen(resolver = ListenExecutingNodeResolver.class, priorityType = PriorityType.ASC) 28 | public @interface ListenExecutingNode { 29 | /** 30 | * 优先级类型(默认为升序) 31 | */ 32 | @AliasFor(annotation = Listen.class, attribute = "priorityType") 33 | PriorityType priorityType() default PriorityType.ASC; 34 | } 35 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/listener/ListenFlowException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 18:41 创建 8 | */ 9 | package org.bekit.flow.annotation.listener; 10 | 11 | import org.bekit.event.annotation.listener.Listen; 12 | import org.bekit.event.listener.PriorityType; 13 | import org.bekit.flow.listener.ListenFlowExceptionResolver; 14 | import org.springframework.core.annotation.AliasFor; 15 | 16 | import java.lang.annotation.*; 17 | 18 | /** 19 | * 监听流程异常事件 20 | *

21 | * 配合@TheFlowListener一起使用;当流程发生异常时,都会调用本注解标注的方法。 22 | * 对应的方法入参类型必须为(Throwable, FlowContext)。 23 | */ 24 | @Target(ElementType.METHOD) 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Documented 27 | @Listen(resolver = ListenFlowExceptionResolver.class, priorityType = PriorityType.ASC) 28 | public @interface ListenFlowException { 29 | /** 30 | * 优先级类型(默认为升序) 31 | */ 32 | @AliasFor(annotation = Listen.class, attribute = "priorityType") 33 | PriorityType priorityType() default PriorityType.ASC; 34 | } 35 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/listener/ListenDecidedStateNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-17 17:06 创建 8 | */ 9 | package org.bekit.flow.annotation.listener; 10 | 11 | import org.bekit.event.annotation.listener.Listen; 12 | import org.bekit.event.listener.PriorityType; 13 | import org.bekit.flow.listener.ListenDecidedStateNodeResolver; 14 | import org.springframework.core.annotation.AliasFor; 15 | 16 | import java.lang.annotation.*; 17 | 18 | /** 19 | * 监听被选择的状态节点 20 | *

21 | * 配合@TheFlowListener一起使用;当每次节点决策器选择下一个状态节点时,都会调用本注解标注的方法。 22 | * 对应的方法入参类型必须为(String, FlowContext)。 23 | */ 24 | @Target(ElementType.METHOD) 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Documented 27 | @Listen(resolver = ListenDecidedStateNodeResolver.class, priorityType = PriorityType.ASC) 28 | public @interface ListenDecidedStateNode { 29 | /** 30 | * 优先级类型(默认为升序) 31 | */ 32 | @AliasFor(annotation = Listen.class, attribute = "priorityType") 33 | PriorityType priorityType() default PriorityType.ASC; 34 | } 35 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/annotation/flow/Flow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-14 21:27 创建 8 | */ 9 | package org.bekit.flow.annotation.flow; 10 | 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.lang.annotation.*; 14 | 15 | /** 16 | * 流程 17 | *

18 | * 流程包含的节点类型:开始节点(@StartNode)、阶段节点(@PhaseNode)、瞬态节点(@TransientNode)、暂停节点(@PauseNode)、结束节点(@EndNode) 19 | * 执行步骤: 20 | * 1、节点初始化为开始节点(@StartNode) 21 | * 2、调用流程映射器映射出要真正执行的节点(如果存在) 22 | * 3、调用流程加锁器流程加锁(如果存在,并调用流程映射器映射出要真正执行的节点(如果存在)) 23 | * 4、开启事务 24 | * 5、调用流程加锁器状态加锁(如果存在,并调用流程映射器映射出要真正执行的节点(如果存在)) 25 | * 6、执行节点并得到下一个节点 26 | * 7、下一个节点是瞬态节点(@TransientNode)则进入步骤6;否则进入步骤8 27 | * 8、调用流程加锁器状态解锁(如果存在) 28 | * 9、提交事务 29 | * 10、下一个节点是暂停节点(@PauseNode)或结束节点(@EndNode),则进入步骤11;否则进入步骤4 30 | * 11、调用流程加锁器流程解锁(如果存在) 31 | */ 32 | @Target(ElementType.TYPE) 33 | @Retention(RetentionPolicy.RUNTIME) 34 | @Documented 35 | @Component 36 | public @interface Flow { 37 | /** 38 | * 流程名称(默认使用被注解的类名且首字母小写) 39 | */ 40 | String name() default ""; 41 | } 42 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/extension/support/ClassListenResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 11:54 创建 8 | */ 9 | package org.bekit.event.extension.support; 10 | 11 | import org.bekit.event.extension.ListenResolver; 12 | import org.springframework.util.Assert; 13 | 14 | import java.lang.reflect.Method; 15 | 16 | /** 17 | * Class监听解决器(监听方法只能有一个入参,事件类型就是入参的Class类) 18 | */ 19 | public class ClassListenResolver implements ListenResolver { 20 | // 监听的事件类型 21 | private Class eventType; 22 | 23 | @Override 24 | public void init(Method listenMethod) { 25 | // 校验入参 26 | Class[] parameterTypes = listenMethod.getParameterTypes(); 27 | Assert.isTrue(parameterTypes.length == 1, String.format("监听方法[%s]必须只有一个入参", listenMethod)); 28 | // 设置事件类型 29 | eventType = parameterTypes[0]; 30 | } 31 | 32 | @Override 33 | public Object getEventType() { 34 | return eventType; 35 | } 36 | 37 | @Override 38 | public Object[] resolveParams(Object event) { 39 | return new Object[]{event}; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/listener/TheFlowEventType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 19:53 创建 8 | */ 9 | package org.bekit.flow.listener; 10 | 11 | import lombok.AllArgsConstructor; 12 | import org.apache.commons.lang3.StringUtils; 13 | 14 | import java.util.Objects; 15 | 16 | /** 17 | * 特定流程事件类型 18 | */ 19 | @AllArgsConstructor 20 | public class TheFlowEventType { 21 | // 流程 22 | private final String flow; 23 | // 类型 24 | private final Class eventClass; 25 | 26 | @Override 27 | public int hashCode() { 28 | return Objects.hash(flow, eventClass); 29 | } 30 | 31 | @Override 32 | public boolean equals(Object obj) { 33 | if (!(obj instanceof TheFlowEventType)) { 34 | return false; 35 | } 36 | TheFlowEventType other = (TheFlowEventType) obj; 37 | return StringUtils.equals(flow, other.flow) && eventClass == other.eventClass; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return String.format("TheFlowEventType{flow=\"%s\",eventClass=%s}", flow, eventClass); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/processor/ProcessorExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-18 11:35 创建 8 | */ 9 | package org.bekit.flow.processor; 10 | 11 | import lombok.Getter; 12 | import org.bekit.common.method.MethodExecutor; 13 | import org.bekit.flow.engine.FlowContext; 14 | 15 | import java.lang.reflect.Method; 16 | 17 | /** 18 | * 处理器执行器 19 | */ 20 | @Getter 21 | public class ProcessorExecutor extends MethodExecutor { 22 | // 处理器名称 23 | private final String processorName; 24 | // 处理器 25 | private final Object processor; 26 | 27 | public ProcessorExecutor(String processorName, Object processor, Method executeMethod) { 28 | super(executeMethod); 29 | this.processorName = processorName; 30 | this.processor = processor; 31 | } 32 | 33 | /** 34 | * 执行处理器 35 | * 36 | * @param context 流程上下文 37 | * @return Execute类型方法返回的结果 38 | * @throws Throwable 执行过程中发生任何异常都后会往外抛 39 | */ 40 | public Object execute(FlowContext context) throws Throwable { 41 | return execute(processor, new Object[]{context}); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/mapper/TheFlowMapperExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-22 16:51 创建 8 | */ 9 | package org.bekit.flow.mapper; 10 | 11 | import lombok.Getter; 12 | import org.bekit.common.method.MethodExecutor; 13 | import org.bekit.flow.engine.FlowContext; 14 | 15 | import java.lang.reflect.Method; 16 | 17 | /** 18 | * 特定流程映射器执行器 19 | */ 20 | @Getter 21 | public class TheFlowMapperExecutor extends MethodExecutor { 22 | // 映射的流程 23 | private final String flow; 24 | // 特定流程映射器 25 | private final Object theFlowMapper; 26 | 27 | public TheFlowMapperExecutor(String flow, Object theFlowMapper, Method mappingNodeMethod) { 28 | super(mappingNodeMethod); 29 | this.flow = flow; 30 | this.theFlowMapper = theFlowMapper; 31 | } 32 | 33 | /** 34 | * 执行 35 | * 36 | * @param context 流程上下文 37 | * @return 映射出的节点名称 38 | * @throws Throwable 执行过程中发生任何异常都后会往外抛 39 | */ 40 | public String execute(FlowContext context) throws Throwable { 41 | return (String) execute(theFlowMapper, new Object[]{context}); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /common/src/main/java/org/bekit/common/scanner/AbstractScanner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-24 22:23 创建 8 | */ 9 | package org.bekit.common.scanner; 10 | 11 | import lombok.AllArgsConstructor; 12 | import org.springframework.context.ApplicationListener; 13 | import org.springframework.context.event.ContextRefreshedEvent; 14 | 15 | import java.lang.annotation.Annotation; 16 | 17 | /** 18 | * 抽象扫描器 19 | */ 20 | @AllArgsConstructor 21 | public abstract class AbstractScanner implements ApplicationListener { 22 | // 需扫描的注解类型 23 | private final Class annotationType; 24 | 25 | @Override 26 | public void onApplicationEvent(ContextRefreshedEvent event) { 27 | // 扫描 28 | String[] beanNames = event.getApplicationContext().getBeanNamesForAnnotation(annotationType); 29 | for (String beanName : beanNames) { 30 | onScan(event.getApplicationContext().getBean(beanName)); 31 | } 32 | } 33 | 34 | /** 35 | * 扫描模版方法 36 | * 37 | * @param obj 扫描到的对象 38 | */ 39 | protected abstract void onScan(Object obj); 40 | } 41 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/bus/EventBusHub.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event.bus; 10 | 11 | import org.bekit.event.extension.ListenerType; 12 | import org.bekit.event.listener.ListenerParser; 13 | 14 | import java.util.Collections; 15 | import java.util.Map; 16 | import java.util.Set; 17 | import java.util.concurrent.ConcurrentHashMap; 18 | 19 | /** 20 | * 事件总线中心 21 | */ 22 | public class EventBusHub { 23 | // 事件总线Map(key:总线类型) 24 | private final Map, EventBus> eventBusMap = new ConcurrentHashMap<>(); 25 | 26 | /** 27 | * 获取所有类型 28 | * 29 | * @return 所有类型 30 | */ 31 | public Set> getTypes() { 32 | return Collections.unmodifiableSet(eventBusMap.keySet()); 33 | } 34 | 35 | /** 36 | * 获取事件总线(如果不存在该类型的事件总线,则新创建一个) 37 | * 38 | * @param type 总线类型 39 | * @return 事件总线 40 | */ 41 | public EventBus getEventBus(Class type) { 42 | return eventBusMap.computeIfAbsent(type, k -> new EventBus(ListenerParser.parseToEventTypeResolver(k))); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /event/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.bekit 8 | bekit 9 | 1.3.0.RELEASE 10 | 11 | 12 | event 13 | event 14 | 15 | 16 | 17 | org.bekit 18 | common 19 | ${project.parent.version} 20 | 21 | 22 | org.springframework 23 | spring-context 24 | provided 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-autoconfigure 29 | provided 30 | true 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.bekit 8 | bekit 9 | 1.3.0.RELEASE 10 | 11 | 12 | service 13 | service 14 | 15 | 16 | 17 | org.bekit 18 | event 19 | ${project.parent.version} 20 | 21 | 22 | org.springframework 23 | spring-context 24 | provided 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-autoconfigure 29 | provided 30 | true 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /common/src/main/java/org/bekit/common/method/MethodExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 19:09 创建 8 | */ 9 | package org.bekit.common.method; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | 14 | import java.lang.reflect.InvocationTargetException; 15 | import java.lang.reflect.Method; 16 | 17 | /** 18 | * 方法执行器 19 | */ 20 | @AllArgsConstructor 21 | @Getter 22 | public abstract class MethodExecutor { 23 | // 方法 24 | private final Method method; 25 | 26 | /** 27 | * 执行方法 28 | * 29 | * @param obj 被执行的对象 30 | * @param args 需传入目标方法的参数 31 | * @return 方法返回的结果 32 | * @throws Throwable 执行过程中发生任何异常都会往外抛 33 | */ 34 | protected Object execute(Object obj, Object[] args) throws Throwable { 35 | try { 36 | return method.invoke(obj, args); 37 | } catch (InvocationTargetException e) { 38 | // 抛出原始异常 39 | throw e.getTargetException(); 40 | } 41 | } 42 | 43 | /** 44 | * 获取方法入参类型 45 | */ 46 | public Class[] getParameterTypes() { 47 | return method.getParameterTypes(); 48 | } 49 | 50 | /** 51 | * 获取方法返回类型 52 | */ 53 | public Class getReturnType() { 54 | return method.getReturnType(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /common/src/main/java/org/bekit/common/registrar/AbstractRegistrar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-19 01:26 创建 8 | */ 9 | package org.bekit.common.registrar; 10 | 11 | import lombok.AllArgsConstructor; 12 | 13 | import java.util.Collections; 14 | import java.util.Map; 15 | import java.util.Set; 16 | import java.util.concurrent.ConcurrentHashMap; 17 | import java.util.function.Function; 18 | 19 | /** 20 | * 抽象注册器 21 | */ 22 | @AllArgsConstructor 23 | public abstract class AbstractRegistrar { 24 | // 元素集 25 | private final Map elementMap = new ConcurrentHashMap<>(); 26 | // 名称提取器 27 | private final Function nameExtractor; 28 | 29 | /** 30 | * 注册元素 31 | * 32 | * @param element 被注册的元素 33 | * @return 被替换的元素 34 | */ 35 | public E register(E element) { 36 | return elementMap.put(nameExtractor.apply(element), element); 37 | } 38 | 39 | /** 40 | * 获取所有元素的名称 41 | * 42 | * @return 所有所有元素的名称 43 | */ 44 | public Set getNames() { 45 | return Collections.unmodifiableSet(elementMap.keySet()); 46 | } 47 | 48 | /** 49 | * 获取元素 50 | * 51 | * @param name 元素名称 52 | * @return 元素 53 | */ 54 | public E get(N name) { 55 | return elementMap.get(name); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.bekit 8 | bekit 9 | 1.3.0.RELEASE 10 | 11 | 12 | common 13 | common 14 | 15 | 16 | 17 | org.apache.commons 18 | commons-lang3 19 | 20 | 21 | org.slf4j 22 | slf4j-api 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-autoconfigure 27 | provided 28 | true 29 | 30 | 31 | org.springframework 32 | spring-tx 33 | provided 34 | true 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /flow/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.bekit 8 | bekit 9 | 1.3.0.RELEASE 10 | 11 | 12 | flow 13 | flow 14 | 15 | 16 | 17 | org.bekit 18 | event 19 | ${project.parent.version} 20 | 21 | 22 | org.springframework 23 | spring-context 24 | provided 25 | 26 | 27 | org.springframework 28 | spring-tx 29 | provided 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-autoconfigure 34 | provided 35 | true 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/engine/DefaultFlowEngine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-19 01:49 创建 8 | */ 9 | package org.bekit.flow.engine; 10 | 11 | import lombok.AllArgsConstructor; 12 | import org.apache.commons.lang3.exception.ExceptionUtils; 13 | import org.bekit.flow.FlowEngine; 14 | import org.bekit.flow.flow.FlowExecutor; 15 | import org.bekit.flow.flow.FlowRegistrar; 16 | import org.springframework.util.Assert; 17 | 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | 21 | /** 22 | * 流程引擎默认实现类 23 | */ 24 | @AllArgsConstructor 25 | public class DefaultFlowEngine implements FlowEngine { 26 | // 流程注册器 27 | private final FlowRegistrar flowRegistrar; 28 | 29 | @Override 30 | public T execute(String flow, T target) { 31 | return execute(flow, target, null); 32 | } 33 | 34 | @Override 35 | public T execute(String flow, T target, Map attachment) { 36 | Assert.notNull(target, "目标对象不能为null"); 37 | attachment = attachment != null ? attachment : new HashMap<>(); 38 | // 构建流程上下文 39 | FlowContext context = new FlowContext<>(target, attachment); 40 | // 获取流程执行器 41 | FlowExecutor flowExecutor = flowRegistrar.get(flow); 42 | if (flowExecutor == null) { 43 | throw new IllegalArgumentException(String.format("流程[%s]不存在", flow)); 44 | } 45 | try { 46 | // 执行流程 47 | flowExecutor.execute(context); 48 | } catch (Throwable e) { 49 | ExceptionUtils.rethrow(e); 50 | } 51 | 52 | return context.getTarget(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/listener/ListenFlowEndResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 20:57 创建 8 | */ 9 | package org.bekit.flow.listener; 10 | 11 | import org.bekit.event.extension.ListenResolver; 12 | import org.bekit.flow.annotation.listener.TheFlowListener; 13 | import org.bekit.flow.engine.FlowContext; 14 | import org.bekit.flow.event.FlowEndEvent; 15 | import org.springframework.core.annotation.AnnotatedElementUtils; 16 | import org.springframework.util.Assert; 17 | 18 | import java.lang.reflect.Method; 19 | 20 | /** 21 | * 监听注解@ListenFlowEnd的解决器 22 | */ 23 | public class ListenFlowEndResolver implements ListenResolver { 24 | // 监听的事件类型 25 | private TheFlowEventType eventType; 26 | 27 | @Override 28 | public void init(Method listenMethod) { 29 | TheFlowListener theFlowListenerAnnotation = AnnotatedElementUtils.findMergedAnnotation(listenMethod.getDeclaringClass(), TheFlowListener.class); 30 | if (theFlowListenerAnnotation == null) { 31 | throw new IllegalArgumentException("@ListenFlowEnd只能标注在特定流程监听器(@TheFlowListener)的方法上"); 32 | } 33 | // 校验入参类型 34 | Class[] parameterTypes = listenMethod.getParameterTypes(); 35 | Assert.isTrue(parameterTypes.length == 1 && parameterTypes[0] == FlowContext.class, String.format("@ListenFlowEnd方法[%s]的入参类型必须是(FlowContext)", listenMethod)); 36 | 37 | eventType = new TheFlowEventType(theFlowListenerAnnotation.flow(), FlowEndEvent.class); 38 | } 39 | 40 | @Override 41 | public Object getEventType() { 42 | return eventType; 43 | } 44 | 45 | @Override 46 | public Object[] resolveParams(Object event) { 47 | FlowEndEvent flowEndEvent = (FlowEndEvent) event; 48 | return new Object[]{flowEndEvent.getContext()}; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /common/src/main/java/org/bekit/common/transaction/TxExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.common.transaction; 10 | 11 | import lombok.AllArgsConstructor; 12 | 13 | /** 14 | * 事务执行器 15 | */ 16 | @AllArgsConstructor 17 | public class TxExecutor { 18 | // 事务持有器 19 | private final ThreadLocal txStatusHolder = new ThreadLocal<>(); 20 | // 事务管理器 21 | private final TransactionManager transactionManager; 22 | // 事务定义 23 | private final TransactionManager.TransactionType transactionType; 24 | 25 | /** 26 | * 创建事务 27 | * 28 | * @throws IllegalStateException 如果已存在事务 29 | */ 30 | public void createTx() { 31 | Object txStatus = txStatusHolder.get(); 32 | if (txStatus != null) { 33 | throw new IllegalStateException("事务已存在,不能同时创建多个事务"); 34 | } 35 | txStatus = transactionManager.getTransaction(transactionType); 36 | txStatusHolder.set(txStatus); 37 | } 38 | 39 | /** 40 | * 提交事务 41 | * 42 | * @throws IllegalStateException 如果不存在事务 43 | */ 44 | public void commitTx() { 45 | Object txStatus = txStatusHolder.get(); 46 | if (txStatus == null) { 47 | throw new IllegalStateException("事务不存在,无法提交事务"); 48 | } 49 | txStatusHolder.remove(); 50 | transactionManager.commit(txStatus); 51 | } 52 | 53 | /** 54 | * 回滚事务 55 | * 56 | * @throws IllegalStateException 如果不存在事务 57 | */ 58 | public void rollbackTx() { 59 | Object txStatus = txStatusHolder.get(); 60 | if (txStatus == null) { 61 | throw new IllegalStateException("事务不存在,无法回滚事务"); 62 | } 63 | txStatusHolder.remove(); 64 | transactionManager.rollback(txStatus); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/listener/ListenFlowStartResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 20:57 创建 8 | */ 9 | package org.bekit.flow.listener; 10 | 11 | import org.bekit.event.extension.ListenResolver; 12 | import org.bekit.flow.annotation.listener.TheFlowListener; 13 | import org.bekit.flow.engine.FlowContext; 14 | import org.bekit.flow.event.FlowStartEvent; 15 | import org.springframework.core.annotation.AnnotatedElementUtils; 16 | import org.springframework.util.Assert; 17 | 18 | import java.lang.reflect.Method; 19 | 20 | /** 21 | * 监听注解@ListenFlowStart的解决器 22 | */ 23 | public class ListenFlowStartResolver implements ListenResolver { 24 | // 监听的事件类型 25 | private TheFlowEventType eventType; 26 | 27 | @Override 28 | public void init(Method listenMethod) { 29 | TheFlowListener theFlowListenerAnnotation = AnnotatedElementUtils.findMergedAnnotation(listenMethod.getDeclaringClass(), TheFlowListener.class); 30 | if (theFlowListenerAnnotation == null) { 31 | throw new IllegalArgumentException("@ListenFlowStart只能标注在特定流程监听器(@TheFlowListener)的方法上"); 32 | } 33 | // 校验入参类型 34 | Class[] parameterTypes = listenMethod.getParameterTypes(); 35 | Assert.isTrue(parameterTypes.length == 1 && parameterTypes[0] == FlowContext.class, String.format("@ListenFlowStart方法[%s]的入参类型必须是(FlowContext)", listenMethod)); 36 | 37 | eventType = new TheFlowEventType(theFlowListenerAnnotation.flow(), FlowStartEvent.class); 38 | } 39 | 40 | @Override 41 | public Object getEventType() { 42 | return eventType; 43 | } 44 | 45 | @Override 46 | public Object[] resolveParams(Object event) { 47 | FlowStartEvent flowStartEvent = (FlowStartEvent) event; 48 | return new Object[]{flowStartEvent.getContext()}; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/listener/ListenerHub.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event.listener; 10 | 11 | import org.bekit.event.extension.ListenerType; 12 | 13 | import java.util.Collections; 14 | import java.util.HashSet; 15 | import java.util.Map; 16 | import java.util.Set; 17 | import java.util.concurrent.ConcurrentHashMap; 18 | 19 | /** 20 | * 监听器中心 21 | */ 22 | public class ListenerHub { 23 | // 监听器执行器Map(key:监听器的类型) 24 | private final Map, Set> listenerExecutorMap = new ConcurrentHashMap<>(); 25 | 26 | /** 27 | * 新增监听器 28 | * 29 | * @param listenerExecutor 监听器执行器 30 | */ 31 | public void addListener(ListenerExecutor listenerExecutor) { 32 | listenerExecutorMap.compute(listenerExecutor.getType(), (type, listenerExecutors) -> { 33 | if (listenerExecutors == null) { 34 | listenerExecutors = new HashSet<>(); 35 | } 36 | listenerExecutors.add(listenerExecutor); 37 | return listenerExecutors; 38 | }); 39 | } 40 | 41 | /** 42 | * 获取所有的监听器类型 43 | * 44 | * @return 所有的监听器类型 45 | */ 46 | public Set> getTypes() { 47 | return Collections.unmodifiableSet(listenerExecutorMap.keySet()); 48 | } 49 | 50 | /** 51 | * 获取指定类型的所有监听器 52 | * 53 | * @param type 类型 54 | * @return 指定类型的所有监听器 55 | */ 56 | public Set getListeners(Class type) { 57 | Set listenerExecutors = listenerExecutorMap.get(type); 58 | if (listenerExecutors == null) { 59 | listenerExecutors = new HashSet<>(); 60 | } 61 | return Collections.unmodifiableSet(listenerExecutors); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/listener/DefaultFlowListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-04-04 20:15 创建 8 | */ 9 | package org.bekit.flow.listener; 10 | 11 | import org.bekit.event.EventPublisher; 12 | import org.bekit.event.annotation.Listen; 13 | import org.bekit.event.bus.EventBusHub; 14 | import org.bekit.event.publisher.DefaultEventPublisher; 15 | import org.bekit.flow.annotation.listener.FlowListener; 16 | import org.bekit.flow.event.*; 17 | 18 | /** 19 | * 默认的流程监听器 20 | *

21 | * 监听所有流程发生的事件,然后将事件转发给对应流程的特定流程监听器(@TheFlowListener) 22 | */ 23 | @FlowListener 24 | public class DefaultFlowListener { 25 | // 特定流程事件发布器 26 | private final EventPublisher eventPublisher; 27 | 28 | public DefaultFlowListener(EventBusHub eventBusHub) { 29 | eventPublisher = new DefaultEventPublisher(eventBusHub.getEventBus(TheFlowListenerType.class)); 30 | } 31 | 32 | // 监听流程开始事件 33 | @Listen 34 | public void listenFlowStartEvent(FlowStartEvent event) { 35 | eventPublisher.publish(event); 36 | } 37 | 38 | // 监听正在执行的节点事件 39 | @Listen 40 | public void listenExecutingNodeEvent(ExecutingNodeEvent event) { 41 | eventPublisher.publish(event); 42 | } 43 | 44 | // 监听节点选择事件 45 | @Listen 46 | public void listenDecidedNodeEvent(DecidedNodeEvent event) { 47 | eventPublisher.publish(event); 48 | } 49 | 50 | // 监听状态节点选择事件 51 | @Listen 52 | public void listenStateNodeDecidedEvent(DecidedStateNodeEvent event) { 53 | eventPublisher.publish(event); 54 | } 55 | 56 | // 监听流程异常事件 57 | @Listen 58 | public void listenFlowExceptionEvent(FlowExceptionEvent event) { 59 | eventPublisher.publish(event); 60 | } 61 | 62 | // 监听流程结束事件 63 | @Listen 64 | public void listenFlowEndEvent(FlowEndEvent event) { 65 | eventPublisher.publish(event); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/listener/ListenDecidedNodeResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 20:29 创建 8 | */ 9 | package org.bekit.flow.listener; 10 | 11 | import org.bekit.event.extension.ListenResolver; 12 | import org.bekit.flow.annotation.listener.TheFlowListener; 13 | import org.bekit.flow.engine.FlowContext; 14 | import org.bekit.flow.event.DecidedNodeEvent; 15 | import org.springframework.core.annotation.AnnotatedElementUtils; 16 | import org.springframework.util.Assert; 17 | 18 | import java.lang.reflect.Method; 19 | 20 | /** 21 | * 监听注解@ListenDecidedNode的解决器 22 | */ 23 | public class ListenDecidedNodeResolver implements ListenResolver { 24 | // 监听的事件类型 25 | private TheFlowEventType eventType; 26 | 27 | @Override 28 | public void init(Method listenMethod) { 29 | TheFlowListener theFlowListenerAnnotation = AnnotatedElementUtils.findMergedAnnotation(listenMethod.getDeclaringClass(), TheFlowListener.class); 30 | if (theFlowListenerAnnotation == null) { 31 | throw new IllegalArgumentException("@ListenDecidedNode只能标注在特定流程监听器(@TheFlowListener)的方法上"); 32 | } 33 | // 校验入参类型 34 | Class[] parameterTypes = listenMethod.getParameterTypes(); 35 | Assert.isTrue(parameterTypes.length == 2 36 | && parameterTypes[0] == String.class 37 | && parameterTypes[1] == FlowContext.class, String.format("@ListenDecidedNode方法[%s]的入参类型必须是(String, FlowContext)", listenMethod)); 38 | 39 | eventType = new TheFlowEventType(theFlowListenerAnnotation.flow(), DecidedNodeEvent.class); 40 | } 41 | 42 | @Override 43 | public Object getEventType() { 44 | return eventType; 45 | } 46 | 47 | @Override 48 | public Object[] resolveParams(Object event) { 49 | DecidedNodeEvent decidedNodeEvent = (DecidedNodeEvent) event; 50 | return new Object[]{decidedNodeEvent.getNode(), decidedNodeEvent.getContext()}; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/listener/ListenExecutingNodeResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 20:29 创建 8 | */ 9 | package org.bekit.flow.listener; 10 | 11 | import org.bekit.event.extension.ListenResolver; 12 | import org.bekit.flow.annotation.listener.TheFlowListener; 13 | import org.bekit.flow.engine.FlowContext; 14 | import org.bekit.flow.event.ExecutingNodeEvent; 15 | import org.springframework.core.annotation.AnnotatedElementUtils; 16 | import org.springframework.util.Assert; 17 | 18 | import java.lang.reflect.Method; 19 | 20 | /** 21 | * 监听注解@ListenExecutingNode的解决器 22 | */ 23 | public class ListenExecutingNodeResolver implements ListenResolver { 24 | // 监听的事件类型 25 | private TheFlowEventType eventType; 26 | 27 | @Override 28 | public void init(Method listenMethod) { 29 | TheFlowListener theFlowListenerAnnotation = AnnotatedElementUtils.findMergedAnnotation(listenMethod.getDeclaringClass(), TheFlowListener.class); 30 | if (theFlowListenerAnnotation == null) { 31 | throw new IllegalArgumentException("@ListenExecutingNode只能标注在特定流程监听器(@TheFlowListener)的方法上"); 32 | } 33 | // 校验入参类型 34 | Class[] parameterTypes = listenMethod.getParameterTypes(); 35 | Assert.isTrue(parameterTypes.length == 2 36 | && parameterTypes[0] == String.class 37 | && parameterTypes[1] == FlowContext.class, String.format("@ListenExecutingNode方法[%s]的入参类型必须是(String, FlowContext)", listenMethod)); 38 | 39 | eventType = new TheFlowEventType(theFlowListenerAnnotation.flow(), ExecutingNodeEvent.class); 40 | } 41 | 42 | @Override 43 | public Object getEventType() { 44 | return eventType; 45 | } 46 | 47 | @Override 48 | public Object[] resolveParams(Object event) { 49 | ExecutingNodeEvent executingNodeEvent = (ExecutingNodeEvent) event; 50 | return new Object[]{executingNodeEvent.getNode(), executingNodeEvent.getContext()}; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/listener/ListenFlowExceptionResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 20:57 创建 8 | */ 9 | package org.bekit.flow.listener; 10 | 11 | import org.bekit.event.extension.ListenResolver; 12 | import org.bekit.flow.annotation.listener.TheFlowListener; 13 | import org.bekit.flow.engine.FlowContext; 14 | import org.bekit.flow.event.FlowExceptionEvent; 15 | import org.springframework.core.annotation.AnnotatedElementUtils; 16 | import org.springframework.util.Assert; 17 | 18 | import java.lang.reflect.Method; 19 | 20 | /** 21 | * 监听注解@ListenFlowException的解决器 22 | */ 23 | public class ListenFlowExceptionResolver implements ListenResolver { 24 | // 监听的事件类型 25 | private TheFlowEventType eventType; 26 | 27 | @Override 28 | public void init(Method listenMethod) { 29 | TheFlowListener theFlowListenerAnnotation = AnnotatedElementUtils.findMergedAnnotation(listenMethod.getDeclaringClass(), TheFlowListener.class); 30 | if (theFlowListenerAnnotation == null) { 31 | throw new IllegalArgumentException("@ListenFlowException只能标注在特定流程监听器(@TheFlowListener)的方法上"); 32 | } 33 | // 校验入参类型 34 | Class[] parameterTypes = listenMethod.getParameterTypes(); 35 | Assert.isTrue(parameterTypes.length == 2 36 | && parameterTypes[0] == Throwable.class 37 | && parameterTypes[1] == FlowContext.class, String.format("@ListenFlowException方法[%s]的入参类型必须是(Throwable, FlowContext)", listenMethod)); 38 | 39 | eventType = new TheFlowEventType(theFlowListenerAnnotation.flow(), FlowExceptionEvent.class); 40 | } 41 | 42 | @Override 43 | public Object getEventType() { 44 | return eventType; 45 | } 46 | 47 | @Override 48 | public Object[] resolveParams(Object event) { 49 | FlowExceptionEvent flowExceptionEvent = (FlowExceptionEvent) event; 50 | return new Object[]{flowExceptionEvent.getThrowable(), flowExceptionEvent.getContext()}; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/listener/ListenDecidedStateNodeResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 20:29 创建 8 | */ 9 | package org.bekit.flow.listener; 10 | 11 | import org.bekit.event.extension.ListenResolver; 12 | import org.bekit.flow.annotation.listener.TheFlowListener; 13 | import org.bekit.flow.engine.FlowContext; 14 | import org.bekit.flow.event.DecidedStateNodeEvent; 15 | import org.springframework.core.annotation.AnnotatedElementUtils; 16 | import org.springframework.util.Assert; 17 | 18 | import java.lang.reflect.Method; 19 | 20 | /** 21 | * 监听注解@ListenDecidedNode的解决器 22 | */ 23 | public class ListenDecidedStateNodeResolver implements ListenResolver { 24 | // 监听的事件类型 25 | private TheFlowEventType eventType; 26 | 27 | @Override 28 | public void init(Method listenMethod) { 29 | TheFlowListener theFlowListenerAnnotation = AnnotatedElementUtils.findMergedAnnotation(listenMethod.getDeclaringClass(), TheFlowListener.class); 30 | if (theFlowListenerAnnotation == null) { 31 | throw new IllegalArgumentException("@ListenDecidedStateNode只能标注在特定流程监听器(@TheFlowListener)的方法上"); 32 | } 33 | // 校验入参类型 34 | Class[] parameterTypes = listenMethod.getParameterTypes(); 35 | Assert.isTrue(parameterTypes.length == 2 36 | && parameterTypes[0] == String.class 37 | && parameterTypes[1] == FlowContext.class, String.format("@ListenDecidedStateNode方法[%s]的入参类型必须是(String, FlowContext)", listenMethod)); 38 | 39 | eventType = new TheFlowEventType(theFlowListenerAnnotation.flow(), DecidedStateNodeEvent.class); 40 | } 41 | 42 | @Override 43 | public Object getEventType() { 44 | return eventType; 45 | } 46 | 47 | @Override 48 | public Object[] resolveParams(Object event) { 49 | DecidedStateNodeEvent decidedStateNodeEvent = (DecidedStateNodeEvent) event; 50 | return new Object[]{decidedStateNodeEvent.getNode(), decidedStateNodeEvent.getContext()}; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/listener/TheFlowListenerType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-09-29 20:16 创建 8 | */ 9 | package org.bekit.flow.listener; 10 | 11 | import org.bekit.event.extension.EventTypeResolver; 12 | import org.bekit.event.extension.ListenerType; 13 | import org.bekit.flow.event.*; 14 | 15 | /** 16 | * 特定流程监听器类型 17 | */ 18 | public class TheFlowListenerType implements ListenerType { 19 | @Override 20 | public EventTypeResolver getResolver() { 21 | return TheFlowEventTypeResolver.INSTANCE; 22 | } 23 | 24 | // 特定流程事件类型解决器 25 | private static class TheFlowEventTypeResolver implements EventTypeResolver { 26 | // 实例 27 | private static final TheFlowEventTypeResolver INSTANCE = new TheFlowEventTypeResolver(); 28 | 29 | @Override 30 | public Object resolve(Object event) { 31 | if (event instanceof FlowStartEvent) { 32 | return new TheFlowEventType(((FlowStartEvent) event).getFlow(), FlowStartEvent.class); 33 | } 34 | if (event instanceof ExecutingNodeEvent) { 35 | return new TheFlowEventType(((ExecutingNodeEvent) event).getFlow(), ExecutingNodeEvent.class); 36 | } 37 | if (event instanceof DecidedNodeEvent) { 38 | return new TheFlowEventType(((DecidedNodeEvent) event).getFlow(), DecidedNodeEvent.class); 39 | } 40 | if (event instanceof DecidedStateNodeEvent) { 41 | return new TheFlowEventType(((DecidedStateNodeEvent) event).getFlow(), DecidedStateNodeEvent.class); 42 | } 43 | if (event instanceof FlowExceptionEvent) { 44 | return new TheFlowEventType(((FlowExceptionEvent) event).getFlow(), FlowExceptionEvent.class); 45 | } 46 | if (event instanceof FlowEndEvent) { 47 | return new TheFlowEventType(((FlowEndEvent) event).getFlow(), FlowEndEvent.class); 48 | } 49 | throw new IllegalArgumentException("无法识别的流程事件:" + event); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /common/src/main/java/org/bekit/common/transaction/support/SpringTransactionManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-02 19:29 创建 8 | */ 9 | package org.bekit.common.transaction.support; 10 | 11 | import lombok.AllArgsConstructor; 12 | import org.bekit.common.transaction.TransactionManager; 13 | import org.springframework.transaction.PlatformTransactionManager; 14 | import org.springframework.transaction.TransactionDefinition; 15 | import org.springframework.transaction.TransactionStatus; 16 | import org.springframework.transaction.support.DefaultTransactionDefinition; 17 | 18 | /** 19 | * Spring事务管理器 20 | */ 21 | @AllArgsConstructor 22 | public class SpringTransactionManager implements TransactionManager { 23 | // 融合事务类型定义 24 | private static final TransactionDefinition REQUIRED_DEFINITION = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED); 25 | // 新事务类型定义 26 | private static final TransactionDefinition REQUIRES_NEW_DEFINITION = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW); 27 | // 无事务类型定义 28 | private static final TransactionDefinition NOT_SUPPORTED_DEFINITION = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); 29 | 30 | // 事务管理器 31 | private final PlatformTransactionManager transactionManager; 32 | 33 | @Override 34 | public Object getTransaction(TransactionType type) { 35 | TransactionDefinition definition; 36 | switch (type) { 37 | case REQUIRED: 38 | definition = REQUIRED_DEFINITION; 39 | break; 40 | case REQUIRES_NEW: 41 | definition = REQUIRES_NEW_DEFINITION; 42 | break; 43 | case NOT_SUPPORTED: 44 | definition = NOT_SUPPORTED_DEFINITION; 45 | break; 46 | default: 47 | throw new IllegalArgumentException("type不能为null"); 48 | } 49 | return transactionManager.getTransaction(definition); 50 | } 51 | 52 | @Override 53 | public void commit(Object status) { 54 | transactionManager.commit((TransactionStatus) status); 55 | } 56 | 57 | @Override 58 | public void rollback(Object status) { 59 | transactionManager.rollback((TransactionStatus) status); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /common/src/main/java/org/bekit/common/boot/CommonConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-02 20:37 创建 8 | */ 9 | package org.bekit.common.boot; 10 | 11 | import org.bekit.common.transaction.TransactionManager; 12 | import org.bekit.common.transaction.support.EmptyTransactionManager; 13 | import org.bekit.common.transaction.support.SpringTransactionManager; 14 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 15 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 16 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 17 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; 18 | import org.springframework.context.annotation.Configuration; 19 | import org.springframework.context.annotation.Import; 20 | import org.springframework.transaction.PlatformTransactionManager; 21 | 22 | /** 23 | * 公共配置 24 | */ 25 | @Configuration 26 | public class CommonConfiguration { 27 | /** 28 | * 事务配置 29 | */ 30 | @Configuration 31 | @ConditionalOnMissingBean(TransactionManager.class) 32 | public static class TransactionManagerConfiguration { 33 | /** 34 | * PlatformTransactionManager存在 35 | */ 36 | @Configuration 37 | @ConditionalOnClass(PlatformTransactionManager.class) 38 | public static class PlatformTransactionManagerClassExists { 39 | /** 40 | * Spring事务管理器配置 41 | */ 42 | @Configuration 43 | @ConditionalOnBean(PlatformTransactionManager.class) 44 | @Import(SpringTransactionManager.class) 45 | public static class SpringTransactionManagerConfiguration { 46 | } 47 | 48 | /** 49 | * 空事务管理器配置 50 | */ 51 | @Configuration 52 | @ConditionalOnMissingBean(PlatformTransactionManager.class) 53 | @Import(EmptyTransactionManager.class) 54 | public static class EmptyTransactionManagerConfiguration { 55 | } 56 | } 57 | 58 | /** 59 | * PlatformTransactionManager不存在 60 | */ 61 | @Configuration 62 | @ConditionalOnMissingClass("org.springframework.transaction.PlatformTransactionManager") 63 | @Import(EmptyTransactionManager.class) 64 | public static class PlatformTransactionManagerClassNotExists { 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/locker/TheFlowLockerExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-22 17:55 创建 8 | */ 9 | package org.bekit.flow.locker; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.common.method.MethodExecutor; 14 | import org.bekit.flow.engine.FlowContext; 15 | 16 | import java.lang.reflect.Method; 17 | import java.util.Map; 18 | 19 | /** 20 | * 特定流程加锁器执行器 21 | */ 22 | @AllArgsConstructor 23 | public class TheFlowLockerExecutor { 24 | // 加锁的流程 25 | @Getter 26 | private final String flow; 27 | // 特定流程加锁器 28 | @Getter 29 | private final Object theFlowLocker; 30 | // 加锁或解锁执行器Map(key:解锁或解锁的注解类型) 31 | private final Map, LockOrUnlockExecutor> lockOrUnlockExecutorMap; 32 | 33 | /** 34 | * 是否包含加解锁类型 35 | * 36 | * @param type 加解锁类型 37 | * @return true 包含;false 不包含 38 | */ 39 | public boolean contain(Class type) { 40 | return lockOrUnlockExecutorMap.containsKey(type); 41 | } 42 | 43 | /** 44 | * 执行 45 | * 46 | * @param type 加解锁类型(@FlowLock、@FlowUnlock、@StateLock、@StateUnlock) 47 | * @param context 流程上下文 48 | * @param 目标对象类型 49 | * @return 如果加锁,则为加锁后的目标对象;否则为null 50 | * @throws Throwable 执行过程中发生任何异常都会往外抛 51 | */ 52 | public T execute(Class type, FlowContext context) throws Throwable { 53 | LockOrUnlockExecutor lockOrUnlockExecutor = lockOrUnlockExecutorMap.get(type); 54 | if (lockOrUnlockExecutor == null) { 55 | throw new IllegalArgumentException(String.format("流程[%s]的特定流程加锁器不存在@%s方法", flow, type.getSimpleName())); 56 | } 57 | return lockOrUnlockExecutor.execute(theFlowLocker, context); 58 | } 59 | 60 | /** 61 | * 加锁或解锁执行器 62 | */ 63 | public static class LockOrUnlockExecutor extends MethodExecutor { 64 | public LockOrUnlockExecutor(Method lockOrUnlockMethod) { 65 | super(lockOrUnlockMethod); 66 | } 67 | 68 | /** 69 | * 执行 70 | * 71 | * @param theFlowLocker 特定流程加锁器 72 | * @param context 流程上下文 73 | * @return 如果加锁,则为加锁后的目标对象;否则为null 74 | * @throws Throwable 执行过程中发生任何异常都会往外抛 75 | */ 76 | public T execute(Object theFlowLocker, FlowContext context) throws Throwable { 77 | return (T) execute(theFlowLocker, new Object[]{context}); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/boot/ServiceEngineConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.boot; 10 | 11 | import org.bekit.common.scanner.AbstractScanner; 12 | import org.bekit.common.transaction.TransactionManager; 13 | import org.bekit.event.boot.EventBusConfiguration; 14 | import org.bekit.event.bus.EventBusHub; 15 | import org.bekit.service.annotation.service.Service; 16 | import org.bekit.service.engine.DefaultServiceEngine; 17 | import org.bekit.service.service.ServiceExecutor; 18 | import org.bekit.service.service.ServiceParser; 19 | import org.bekit.service.service.ServiceRegistrar; 20 | import org.springframework.context.annotation.Configuration; 21 | import org.springframework.context.annotation.Import; 22 | import org.springframework.core.annotation.Order; 23 | import org.springframework.util.Assert; 24 | 25 | /** 26 | * 服务引擎配置 27 | */ 28 | @Configuration 29 | @Import({EventBusConfiguration.class, 30 | DefaultServiceEngine.class, 31 | ServiceRegistrar.class, 32 | ServiceEngineConfiguration.ServiceScanner.class}) 33 | public class ServiceEngineConfiguration { 34 | /** 35 | * 优先级 36 | */ 37 | public static final int ORDER = 2000; 38 | 39 | /** 40 | * 服务扫描器 41 | */ 42 | @Order(ORDER) 43 | public static class ServiceScanner extends AbstractScanner { 44 | // 服务注册器 45 | private final ServiceRegistrar serviceRegistrar; 46 | // 事件总线中心 47 | private final EventBusHub eventBusHub; 48 | // 事务管理器 49 | private final TransactionManager transactionManager; 50 | 51 | public ServiceScanner(ServiceRegistrar serviceRegistrar, 52 | EventBusHub eventBusHub, 53 | TransactionManager transactionManager) { 54 | super(Service.class); 55 | this.serviceRegistrar = serviceRegistrar; 56 | this.eventBusHub = eventBusHub; 57 | this.transactionManager = transactionManager; 58 | } 59 | 60 | @Override 61 | protected void onScan(Object obj) { 62 | // 解析 63 | ServiceExecutor serviceExecutor = ServiceParser.parseService(obj, eventBusHub, transactionManager); 64 | // 注册 65 | ServiceExecutor existedOne = serviceRegistrar.register(serviceExecutor); 66 | Assert.isNull(existedOne, String.format("存在重名的服务[%s]", serviceExecutor.getServiceName())); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/engine/DefaultServiceEngine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.engine; 10 | 11 | import lombok.AllArgsConstructor; 12 | import org.bekit.service.ServiceEngine; 13 | import org.bekit.service.service.ServiceExecutor; 14 | import org.bekit.service.service.ServiceRegistrar; 15 | import org.springframework.beans.BeanUtils; 16 | import org.springframework.util.Assert; 17 | 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | 21 | /** 22 | * 服务引擎默认实现类 23 | */ 24 | @AllArgsConstructor 25 | public class DefaultServiceEngine implements ServiceEngine { 26 | // 服务注册器 27 | private final ServiceRegistrar serviceRegistrar; 28 | 29 | @Override 30 | public R execute(String service, O order) { 31 | return execute(service, order, null); 32 | } 33 | 34 | @Override 35 | public R execute(String service, O order, Map attachment) { 36 | // 获取服务执行器 37 | ServiceExecutor serviceExecutor = getServiceExecutor(service); 38 | // 校验order 39 | checkOrder(order, serviceExecutor); 40 | // 构建服务上下文 41 | ServiceContext context = new ServiceContext<>(order, (R) newResult(serviceExecutor), reviseAttachment(attachment)); 42 | // 执行服务 43 | serviceExecutor.execute(context); 44 | 45 | return context.getResult(); 46 | } 47 | 48 | // 获取服务执行器 49 | private ServiceExecutor getServiceExecutor(String service) { 50 | ServiceExecutor serviceExecutor = serviceRegistrar.get(service); 51 | if (serviceExecutor == null) { 52 | throw new IllegalArgumentException(String.format("服务[%s]不存在", service)); 53 | } 54 | return serviceExecutor; 55 | } 56 | 57 | // 校验入参order 58 | private void checkOrder(Object order, ServiceExecutor serviceExecutor) { 59 | Assert.notNull(order, "order不能为null"); 60 | if (!serviceExecutor.getOrderType().isAssignableFrom(order.getClass())) { 61 | throw new IllegalArgumentException(String.format("入参order的类型[%s]和服务[%s]期望的类型不匹配", order.getClass(), serviceExecutor.getServiceName())); 62 | } 63 | } 64 | 65 | // 创建result 66 | private Object newResult(ServiceExecutor serviceExecutor) { 67 | return BeanUtils.instantiate(serviceExecutor.getResultType()); 68 | } 69 | 70 | // 修正附件 71 | private Map reviseAttachment(Map attachment) { 72 | return attachment != null ? attachment : new HashMap<>(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/mapper/TheFlowMapperParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-22 17:04 创建 8 | */ 9 | package org.bekit.flow.mapper; 10 | 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.bekit.flow.annotation.mapper.MappingNode; 13 | import org.bekit.flow.annotation.mapper.TheFlowMapper; 14 | import org.bekit.flow.engine.FlowContext; 15 | import org.springframework.aop.support.AopUtils; 16 | import org.springframework.core.annotation.AnnotatedElementUtils; 17 | import org.springframework.util.Assert; 18 | 19 | import java.lang.reflect.Method; 20 | import java.lang.reflect.Modifier; 21 | 22 | /** 23 | * 特定流程映射器解析器 24 | */ 25 | @Slf4j 26 | public final class TheFlowMapperParser { 27 | /** 28 | * 解析特定流程映射器 29 | * 30 | * @param theFlowMapper 特定流程映射器 31 | * @return 特定流程映射器执行器 32 | */ 33 | public static TheFlowMapperExecutor parseTheFlowMapper(Object theFlowMapper) { 34 | // 获取目标class(应对AOP代理情况) 35 | Class theFlowMapperClass = AopUtils.getTargetClass(theFlowMapper); 36 | log.debug("解析特定流程映射器:{}", theFlowMapperClass); 37 | // 获取映射的流程 38 | TheFlowMapper theFlowMapperAnnotation = AnnotatedElementUtils.findMergedAnnotation(theFlowMapperClass, TheFlowMapper.class); 39 | // 解析处理器方法 40 | Method mappingNodeMethod = parseToMappingNodeMethod(theFlowMapperClass); 41 | 42 | return new TheFlowMapperExecutor(theFlowMapperAnnotation.flow(), theFlowMapper, mappingNodeMethod); 43 | } 44 | 45 | // 解析出@MappingNode方法 46 | private static Method parseToMappingNodeMethod(Class theFlowMapperClass) { 47 | for (Method method : theFlowMapperClass.getDeclaredMethods()) { 48 | if (AnnotatedElementUtils.findMergedAnnotation(method, MappingNode.class) == null) { 49 | continue; 50 | } 51 | // 校验方法类型、返回类型 52 | Assert.isTrue(Modifier.isPublic(method.getModifiers()), String.format("@MappingNode方法[%s]必须是public类型", method)); 53 | Assert.isTrue(method.getReturnType() == String.class, String.format("@MappingNode方法[%s]返回类型必须是String", method)); 54 | // 校验入参类型 55 | Class[] parameterTypes = method.getParameterTypes(); 56 | if (parameterTypes.length != 1 || parameterTypes[0] != FlowContext.class) { 57 | throw new IllegalArgumentException(String.format("@ProcessorExecute方法[%s]的入参必须是(FlowContext context)", method)); 58 | } 59 | 60 | return method; 61 | } 62 | throw new IllegalArgumentException(String.format("特定流程映射器[%s]不存在@MappingNode法", theFlowMapperClass)); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/processor/ProcessorParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-18 12:27 创建 8 | */ 9 | package org.bekit.flow.processor; 10 | 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.apache.commons.lang3.StringUtils; 13 | import org.bekit.flow.annotation.processor.Processor; 14 | import org.bekit.flow.annotation.processor.ProcessorExecute; 15 | import org.bekit.flow.engine.FlowContext; 16 | import org.springframework.aop.support.AopUtils; 17 | import org.springframework.core.annotation.AnnotatedElementUtils; 18 | import org.springframework.util.Assert; 19 | import org.springframework.util.ClassUtils; 20 | 21 | import java.lang.reflect.Method; 22 | import java.lang.reflect.Modifier; 23 | 24 | /** 25 | * 处理器解析器 26 | */ 27 | @Slf4j 28 | public final class ProcessorParser { 29 | /** 30 | * 解析处理器 31 | * 32 | * @param processor 处理器 33 | * @return 处理器执行器 34 | */ 35 | public static ProcessorExecutor parseProcessor(Object processor) { 36 | // 获取目标class(应对AOP代理情况) 37 | Class processorClass = AopUtils.getTargetClass(processor); 38 | log.debug("解析处理器:{}", processorClass); 39 | // 获取处理器名称 40 | Processor processorAnnotation = AnnotatedElementUtils.findMergedAnnotation(processorClass, Processor.class); 41 | String processorName = processorAnnotation.name(); 42 | if (StringUtils.isEmpty(processorName)) { 43 | processorName = ClassUtils.getShortNameAsProperty(processorClass); 44 | } 45 | // 解析出@ProcessorExecute方法 46 | Method executeMethod = parseToExecuteMethod(processorClass); 47 | 48 | return new ProcessorExecutor(processorName, processor, executeMethod); 49 | } 50 | 51 | // 解析出@ProcessorExecute方法 52 | private static Method parseToExecuteMethod(Class processorClass) { 53 | for (Method method : processorClass.getDeclaredMethods()) { 54 | if (AnnotatedElementUtils.findMergedAnnotation(method, ProcessorExecute.class) == null) { 55 | continue; 56 | } 57 | // 校验方法类型 58 | Assert.isTrue(Modifier.isPublic(method.getModifiers()), String.format("@ProcessorExecute方法[%s]必须是public类型", method)); 59 | // 校验入参类型 60 | Class[] parameterTypes = method.getParameterTypes(); 61 | if (parameterTypes.length != 1 || parameterTypes[0] != FlowContext.class) { 62 | throw new IllegalArgumentException(String.format("@ProcessorExecute方法[%s]的入参必须是(FlowContext context)", method)); 63 | } 64 | 65 | return method; 66 | } 67 | throw new IllegalArgumentException(String.format("处理器[%s]不存在@ProcessorExecute方法", processorClass)); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/listener/ListenerExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event.listener; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.common.method.MethodExecutor; 14 | import org.bekit.event.extension.EventTypeResolver; 15 | import org.bekit.event.extension.ListenResolver; 16 | import org.bekit.event.extension.ListenerType; 17 | 18 | import java.lang.reflect.Method; 19 | import java.util.HashSet; 20 | import java.util.Map; 21 | import java.util.Set; 22 | 23 | /** 24 | * 监听器执行器 25 | */ 26 | @AllArgsConstructor 27 | public class ListenerExecutor { 28 | // 监听器类型 29 | @Getter 30 | private final Class type; 31 | // 优先级 32 | @Getter 33 | private final int priority; 34 | // 监听器 35 | @Getter 36 | private final Object listener; 37 | // 事件类型解决器 38 | private final EventTypeResolver resolver; 39 | // 监听执行器map(key:被监听的事件类型) 40 | private final Map listenExecutorMap; 41 | 42 | /** 43 | * 执行监听事件 44 | * 45 | * @param event 事件 46 | * @throws Throwable 执行过程中发生任何异常都会往外抛 47 | */ 48 | public void execute(Object event) throws Throwable { 49 | ListenExecutor listenExecutor = listenExecutorMap.get(resolver.resolve(event)); 50 | if (listenExecutor != null) { 51 | listenExecutor.execute(listener, event); 52 | } 53 | } 54 | 55 | /** 56 | * 获取指定优先级顺序的监听事件类型 57 | * 58 | * @param priorityType 优先级类型 59 | */ 60 | public Set getEventTypes(PriorityType priorityType) { 61 | Set eventTypes = new HashSet<>(); 62 | listenExecutorMap.forEach((eventType, listenExecutor) -> { 63 | if (listenExecutor.getPriorityType() == priorityType) { 64 | eventTypes.add(eventType); 65 | } 66 | }); 67 | return eventTypes; 68 | } 69 | 70 | /** 71 | * 监听执行器 72 | */ 73 | public static class ListenExecutor extends MethodExecutor { 74 | // 监听解决器 75 | private final ListenResolver resolver; 76 | // 是否优先级升序 77 | @Getter 78 | private final PriorityType priorityType; 79 | 80 | public ListenExecutor(ListenResolver resolver, PriorityType priorityType, Method listenMethod) { 81 | super(listenMethod); 82 | this.resolver = resolver; 83 | this.priorityType = priorityType; 84 | } 85 | 86 | /** 87 | * 执行监听 88 | * 89 | * @param listener 监听器 90 | * @param event 事件 91 | * @throws Throwable 执行过程中发生任何异常都会往外抛 92 | */ 93 | public void execute(Object listener, Object event) throws Throwable { 94 | execute(listener, resolver.resolveParams(event)); 95 | } 96 | 97 | /** 98 | * 获取事件类型 99 | */ 100 | public Object getEventType() { 101 | return resolver.getEventType(); 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /common/src/main/java/org/bekit/common/util/EnumUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2017-10-31 20:06 创建 8 | */ 9 | package org.bekit.common.util; 10 | 11 | import java.util.regex.Matcher; 12 | import java.util.regex.Pattern; 13 | 14 | /** 15 | * 枚举工具类 16 | */ 17 | public final class EnumUtils { 18 | // 驼峰命名正则表达式 19 | private static final Pattern CAMEL_CASE_PATTERN = Pattern.compile("[a-z0-9][A-Z]"); 20 | // 枚举命名正则表达式 21 | private static final Pattern ENUM_NAME_PATTERN = Pattern.compile("_+"); 22 | 23 | /** 24 | * 获取枚举 25 | * 26 | * @param enumType 枚举类型 27 | * @param camelCaseName 驼峰命名 28 | * @return 枚举 29 | * @throws IllegalArgumentException 如果不存在该枚举 30 | */ 31 | public static > T getEnum(Class enumType, String camelCaseName) { 32 | return Enum.valueOf(enumType, toEnumName(camelCaseName)); 33 | } 34 | 35 | /** 36 | * 驼峰命名 37 | * 38 | * @param enumObj 枚举对象 39 | * @return 驼峰命名 40 | */ 41 | public static > String getCamelCaseName(T enumObj) { 42 | return toCamelCaseName(enumObj.name()); 43 | } 44 | 45 | /** 46 | * 驼峰命名转枚举名 47 | * 48 | * @param camelCaseName 驼峰命名 49 | * @return 枚举名 50 | */ 51 | public static String toEnumName(String camelCaseName) { 52 | if (camelCaseName == null) { 53 | return null; 54 | } 55 | 56 | Matcher matcher = CAMEL_CASE_PATTERN.matcher(camelCaseName); 57 | StringBuilder builder = new StringBuilder(); 58 | int index = 0; 59 | while (matcher.find()) { 60 | builder.append(camelCaseName.substring(index, matcher.start() + 1)); 61 | builder.append('_'); 62 | index = matcher.end() - 1; 63 | } 64 | builder.append(camelCaseName.substring(index)); 65 | 66 | return builder.toString().toUpperCase(); 67 | } 68 | 69 | /** 70 | * 枚举名转驼峰命名 71 | * 72 | * @param enumName 枚举名 73 | * @return 驼峰命名 74 | */ 75 | public static String toCamelCaseName(String enumName) { 76 | if (enumName == null) { 77 | return null; 78 | } 79 | 80 | Matcher matcher = ENUM_NAME_PATTERN.matcher(enumName); 81 | StringBuilder builder = new StringBuilder(); 82 | int index = 0; 83 | while (matcher.find()) { 84 | String part = enumName.substring(index, matcher.start()); 85 | builder.append(toCamelCasePart(part)); 86 | index = matcher.end(); 87 | } 88 | String part = enumName.substring(index); 89 | builder.append(toCamelCasePart(part)); 90 | if (builder.length() > 0) { 91 | builder.setCharAt(0, Character.toLowerCase(builder.charAt(0))); 92 | } 93 | 94 | return builder.toString(); 95 | } 96 | 97 | // 驼峰命名 98 | private static String toCamelCasePart(String part) { 99 | if (part == null || part.length() == 0) { 100 | return part; 101 | } 102 | part = part.toLowerCase(); 103 | char[] chars = part.toCharArray(); 104 | chars[0] = Character.toUpperCase(chars[0]); 105 | return new String(chars); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/boot/EventBusConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event.boot; 10 | 11 | import lombok.AllArgsConstructor; 12 | import org.bekit.common.boot.CommonConfiguration; 13 | import org.bekit.common.scanner.AbstractScanner; 14 | import org.bekit.event.EventPublisher; 15 | import org.bekit.event.annotation.listener.Listener; 16 | import org.bekit.event.bus.EventBus; 17 | import org.bekit.event.bus.EventBusHub; 18 | import org.bekit.event.extension.ListenerType; 19 | import org.bekit.event.extension.support.DomainListenerType; 20 | import org.bekit.event.listener.ListenerExecutor; 21 | import org.bekit.event.listener.ListenerHub; 22 | import org.bekit.event.listener.ListenerParser; 23 | import org.bekit.event.publisher.DefaultEventPublisher; 24 | import org.springframework.context.ApplicationListener; 25 | import org.springframework.context.annotation.Bean; 26 | import org.springframework.context.annotation.Configuration; 27 | import org.springframework.context.annotation.Import; 28 | import org.springframework.context.event.ContextRefreshedEvent; 29 | import org.springframework.core.annotation.Order; 30 | 31 | /** 32 | * 事件总线配置 33 | */ 34 | @Configuration 35 | @Import({CommonConfiguration.class, 36 | EventBusHub.class, 37 | ListenerHub.class, 38 | EventBusConfiguration.ListenerScanner.class, 39 | EventBusConfiguration.EventBusInitializer.class}) 40 | public class EventBusConfiguration { 41 | /** 42 | * 优先级 43 | */ 44 | public static final int ORDER = 0; 45 | 46 | // 配置领域事件发布器 47 | @Bean 48 | public EventPublisher eventPublisher(EventBusHub eventBusHub) { 49 | return new DefaultEventPublisher(eventBusHub.getEventBus(DomainListenerType.class)); 50 | } 51 | 52 | /** 53 | * 监听器扫描器 54 | */ 55 | @Order(ORDER) 56 | public static class ListenerScanner extends AbstractScanner { 57 | // 监听器中心 58 | private final ListenerHub listenerHub; 59 | 60 | public ListenerScanner(ListenerHub listenerHub) { 61 | super(Listener.class); 62 | this.listenerHub = listenerHub; 63 | } 64 | 65 | @Override 66 | protected void onScan(Object obj) { 67 | // 解析 68 | ListenerExecutor listenerExecutor = ListenerParser.parseListener(obj); 69 | // 注册 70 | listenerHub.addListener(listenerExecutor); 71 | } 72 | } 73 | 74 | /** 75 | * 事件总线初始化器 76 | */ 77 | @Order(ORDER + 100) 78 | @AllArgsConstructor 79 | public static class EventBusInitializer implements ApplicationListener { 80 | // 数据总线中心 81 | private final EventBusHub eventBusHub; 82 | // 监听器中心 83 | private final ListenerHub listenerHub; 84 | 85 | @Override 86 | public void onApplicationEvent(ContextRefreshedEvent event) { 87 | for (Class type : listenerHub.getTypes()) { 88 | // 初始化事件总线 89 | EventBus eventBus = eventBusHub.getEventBus(type); 90 | for (ListenerExecutor listenerExecutor : listenerHub.getListeners(type)) { 91 | eventBus.addListenerExecutor(listenerExecutor); 92 | } 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/listener/ListenerParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event.listener; 10 | 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.bekit.event.annotation.listener.Listen; 13 | import org.bekit.event.annotation.listener.Listener; 14 | import org.bekit.event.extension.EventTypeResolver; 15 | import org.bekit.event.extension.ListenResolver; 16 | import org.bekit.event.extension.ListenerType; 17 | import org.bekit.event.listener.ListenerExecutor.ListenExecutor; 18 | import org.springframework.aop.support.AopUtils; 19 | import org.springframework.beans.BeanUtils; 20 | import org.springframework.core.annotation.AnnotatedElementUtils; 21 | import org.springframework.util.Assert; 22 | import org.springframework.util.ReflectionUtils; 23 | 24 | import java.lang.reflect.Method; 25 | import java.lang.reflect.Modifier; 26 | import java.util.HashMap; 27 | import java.util.Map; 28 | 29 | /** 30 | * 监听器解析器 31 | */ 32 | @Slf4j 33 | public final class ListenerParser { 34 | /** 35 | * 解析监听器 36 | * 37 | * @param listener 监听器 38 | * @return 监听器执行器 39 | */ 40 | public static ListenerExecutor parseListener(Object listener) { 41 | // 获取目标class(应对AOP代理情况) 42 | Class listenerClass = AopUtils.getTargetClass(listener); 43 | log.debug("解析监听器:{}", listenerClass); 44 | Listener listenerAnnotation = AnnotatedElementUtils.findMergedAnnotation(listenerClass, Listener.class); 45 | // 解析 46 | EventTypeResolver resolver = parseToEventTypeResolver(listenerAnnotation.type()); 47 | Map listenExecutorMap = parseToListenExecutors(listenerClass); 48 | 49 | return new ListenerExecutor(listenerAnnotation.type(), listenerAnnotation.priority(), listener, resolver, listenExecutorMap); 50 | } 51 | 52 | /** 53 | * 解析出事件类型解决器 54 | * 55 | * @param type 监听器类型 56 | */ 57 | public static EventTypeResolver parseToEventTypeResolver(Class type) { 58 | ListenerType listenerType = BeanUtils.instantiate(type); 59 | return listenerType.getResolver(); 60 | } 61 | 62 | // 解析出所有监听方法 63 | private static Map parseToListenExecutors(Class listenerClass) { 64 | Map map = new HashMap<>(); 65 | // 解析 66 | ReflectionUtils.doWithLocalMethods(listenerClass, method -> { 67 | Listen listenAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, Listen.class); 68 | if (listenAnnotation != null) { 69 | ListenExecutor listenExecutor = parseListen(listenAnnotation, method); 70 | Assert.isTrue(!map.containsKey(listenExecutor.getEventType()), String.format("监听器[%s]存在监听同一个事件类型[%s]的多个方法", listenerClass, listenExecutor.getEventType())); 71 | map.put(listenExecutor.getEventType(), listenExecutor); 72 | } 73 | }); 74 | 75 | return map; 76 | } 77 | 78 | // 解析监听方法 79 | private static ListenExecutor parseListen(Listen listenAnnotation, Method listenMethod) { 80 | log.debug("解析监听方法:{}", listenMethod); 81 | // 校验方法类型 82 | Assert.isTrue(Modifier.isPublic(listenMethod.getModifiers()), String.format("监听方法[%s]必须是public类型", listenMethod)); 83 | // 创建监听解决器 84 | ListenResolver resolver = BeanUtils.instantiate(listenAnnotation.resolver()); 85 | resolver.init(listenMethod); 86 | 87 | return new ListenExecutor(resolver, listenAnnotation.priorityType(), listenMethod); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/locker/TheFlowLockerParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2019-12-22 18:36 创建 8 | */ 9 | package org.bekit.flow.locker; 10 | 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.bekit.flow.annotation.locker.*; 13 | import org.bekit.flow.engine.FlowContext; 14 | import org.springframework.aop.support.AopUtils; 15 | import org.springframework.core.ResolvableType; 16 | import org.springframework.core.annotation.AnnotatedElementUtils; 17 | import org.springframework.util.Assert; 18 | import org.springframework.util.ReflectionUtils; 19 | 20 | import java.lang.annotation.Annotation; 21 | import java.lang.reflect.Method; 22 | import java.lang.reflect.Modifier; 23 | import java.util.HashMap; 24 | import java.util.Map; 25 | 26 | /** 27 | * 特定流程加锁器解析器 28 | */ 29 | @Slf4j 30 | public final class TheFlowLockerParser { 31 | // 加解锁类型 32 | private static final Class[] LOCK_UNLOCK_TYPES = new Class[]{FlowLock.class, FlowUnlock.class, StateLock.class, StateUnlock.class}; 33 | 34 | /** 35 | * 解析特定流程加锁器 36 | * 37 | * @param theFlowLocker 特定流程加锁器 38 | * @return 特定流程加锁器执行器 39 | */ 40 | public static TheFlowLockerExecutor parseTheFlowLocker(Object theFlowLocker) { 41 | // 获取目标class(应对AOP代理情况) 42 | Class theFlowLockerClass = AopUtils.getTargetClass(theFlowLocker); 43 | log.debug("解析特定流程加锁器:{}", theFlowLockerClass); 44 | // 解析加锁的流程 45 | TheFlowLocker theFlowLockerAnnotation = AnnotatedElementUtils.findMergedAnnotation(theFlowLockerClass, TheFlowLocker.class); 46 | // 解析出所有加解锁 47 | Map, TheFlowLockerExecutor.LockOrUnlockExecutor> lockOrUnlockExecutorMap = parseToLockOrUnlockExecutors(theFlowLockerClass); 48 | 49 | return new TheFlowLockerExecutor(theFlowLockerAnnotation.flow(), theFlowLocker, lockOrUnlockExecutorMap); 50 | } 51 | 52 | // 解析出所有加解锁 53 | private static Map, TheFlowLockerExecutor.LockOrUnlockExecutor> parseToLockOrUnlockExecutors(Class theFlowLockerClass) { 54 | Map, TheFlowLockerExecutor.LockOrUnlockExecutor> executorMap = new HashMap<>(); 55 | // 解析 56 | ReflectionUtils.doWithLocalMethods(theFlowLockerClass, method -> { 57 | for (Class type : LOCK_UNLOCK_TYPES) { 58 | if (AnnotatedElementUtils.findMergedAnnotation(method, type) != null) { 59 | executorMap.put(type, parseLockOrUnlock(type, method)); 60 | } 61 | } 62 | }); 63 | 64 | return executorMap; 65 | } 66 | 67 | // 解析加解锁 68 | private static TheFlowLockerExecutor.LockOrUnlockExecutor parseLockOrUnlock(Class type, Method lockOrUnlockMethod) { 69 | log.debug("解析加解锁方法{}", lockOrUnlockMethod); 70 | // 校验方法类型 71 | Assert.isTrue(Modifier.isPublic(lockOrUnlockMethod.getModifiers()), String.format("@%s方法[%s]必须是public类型", type.getSimpleName(), lockOrUnlockMethod)); 72 | // 校验入参类型 73 | Class[] parameterTypes = lockOrUnlockMethod.getParameterTypes(); 74 | if (parameterTypes.length != 1 || parameterTypes[0] != FlowContext.class) { 75 | throw new IllegalArgumentException(String.format("@%s方法[%s]入参类型必须是(FlowContext)", type.getSimpleName(), lockOrUnlockMethod)); 76 | } 77 | ResolvableType resolvableType = ResolvableType.forMethodParameter(lockOrUnlockMethod, 0); 78 | Class targetType = resolvableType.getGeneric(0).resolve(Object.class); 79 | // 校验返回类型 80 | if (type == FlowLock.class || type == StateLock.class) { 81 | Assert.isTrue(lockOrUnlockMethod.getReturnType() == targetType, String.format("@%s方法[%s]返回类型与FlowContext的目标对象类型必须一致", type.getSimpleName(), lockOrUnlockMethod)); 82 | } else { 83 | Assert.isTrue(lockOrUnlockMethod.getReturnType() == void.class, String.format("@%s方法[%s]返回类型必须为void", type.getSimpleName(), lockOrUnlockMethod)); 84 | } 85 | 86 | return new TheFlowLockerExecutor.LockOrUnlockExecutor(lockOrUnlockMethod); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/service/ServiceExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.service; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.common.method.MethodExecutor; 14 | import org.bekit.common.transaction.TxExecutor; 15 | import org.bekit.event.EventPublisher; 16 | import org.bekit.service.annotation.service.ServiceAfter; 17 | import org.bekit.service.annotation.service.ServiceBefore; 18 | import org.bekit.service.annotation.service.ServiceExecute; 19 | import org.bekit.service.engine.ServiceContext; 20 | import org.bekit.service.event.ServiceApplyEvent; 21 | import org.bekit.service.event.ServiceExceptionEvent; 22 | import org.bekit.service.event.ServiceFinishEvent; 23 | 24 | import java.lang.reflect.Method; 25 | import java.util.Map; 26 | 27 | /** 28 | * 服务执行器 29 | */ 30 | @AllArgsConstructor 31 | public class ServiceExecutor { 32 | // 服务名称 33 | @Getter 34 | private final String serviceName; 35 | // 服务 36 | @Getter 37 | private final Object service; 38 | // 服务阶段执行器Map(key:服务阶段注解的Class) 39 | private final Map, ServicePhaseExecutor> phaseExecutorMap; 40 | // 事件发布器 41 | private final EventPublisher eventPublisher; 42 | // 事务执行器 43 | private final TxExecutor txExecutor; 44 | 45 | /** 46 | * 执行 47 | * 48 | * @param context 服务上下文 49 | */ 50 | public void execute(ServiceContext context) { 51 | try { 52 | // 发布服务申请事件 53 | eventPublisher.publish(new ServiceApplyEvent(serviceName, context)); 54 | // 执行所有服务阶段 55 | executePhases(context); 56 | } catch (Throwable e) { 57 | // 发布服务异常事件 58 | eventPublisher.publish(new ServiceExceptionEvent(serviceName, e, context)); 59 | } finally { 60 | // 发布服务结束事件 61 | eventPublisher.publish(new ServiceFinishEvent(serviceName, context)); 62 | } 63 | } 64 | 65 | // 执行所有服务阶段 66 | private void executePhases(ServiceContext context) throws Throwable { 67 | // 执行服务前置阶段(如果存在) 68 | if (phaseExecutorMap.containsKey(ServiceBefore.class)) { 69 | phaseExecutorMap.get(ServiceBefore.class).execute(service, context); 70 | } 71 | // 执行服务执行阶段 72 | executeServiceExecute(context); 73 | // 执行服务后置阶段(如果存在) 74 | if (phaseExecutorMap.containsKey(ServiceAfter.class)) { 75 | phaseExecutorMap.get(ServiceAfter.class).execute(service, context); 76 | } 77 | } 78 | 79 | // 执行服务执行阶段 80 | private void executeServiceExecute(ServiceContext context) throws Throwable { 81 | if (txExecutor != null) { 82 | // 开启事务 83 | txExecutor.createTx(); 84 | } 85 | try { 86 | phaseExecutorMap.get(ServiceExecute.class).execute(service, context); 87 | if (txExecutor != null) { 88 | // 提交事务 89 | txExecutor.commitTx(); 90 | } 91 | } catch (Throwable e) { 92 | if (txExecutor != null) { 93 | // 回滚事务 94 | txExecutor.rollbackTx(); 95 | } 96 | throw e; 97 | } 98 | } 99 | 100 | /** 101 | * 获取Order的类型 102 | */ 103 | public Class getOrderType() { 104 | return phaseExecutorMap.get(ServiceExecute.class).getOrderType(); 105 | } 106 | 107 | /** 108 | * 获取Result的类型 109 | */ 110 | public Class getResultType() { 111 | return phaseExecutorMap.get(ServiceExecute.class).getResultType(); 112 | } 113 | 114 | /** 115 | * 服务阶段执行器 116 | */ 117 | @Getter 118 | public static class ServicePhaseExecutor extends MethodExecutor { 119 | // ServiceContext泛型O的真实类型 120 | private final Class orderType; 121 | // ServiceContext泛型R的真实类型 122 | private final Class resultType; 123 | 124 | public ServicePhaseExecutor(Method servicePhaseMethod, Class orderType, Class resultType) { 125 | super(servicePhaseMethod); 126 | this.orderType = orderType; 127 | this.resultType = resultType; 128 | } 129 | 130 | /** 131 | * 执行服务阶段 132 | * 133 | * @param service 服务 134 | * @param context 服务上下文 135 | * @throws Throwable 执行过程中发生任何异常都会往外抛 136 | */ 137 | public void execute(Object service, ServiceContext context) throws Throwable { 138 | execute(service, new Object[]{context}); 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.2.4.RELEASE 9 | 10 | 11 | org.bekit 12 | bekit 13 | 1.3.0.RELEASE 14 | pom 15 | 16 | bekit 17 | bekit is a lightweight Java FrameWork 18 | http://bekit.org 19 | 20 | 21 | 22 | 1.8 23 | 24 | 25 | 26 | common 27 | event 28 | flow 29 | service 30 | 31 | 32 | 33 | 34 | 35 | org.apache.commons 36 | commons-lang3 37 | 3.9 38 | 39 | 40 | 41 | 42 | 43 | org.projectlombok 44 | lombok 45 | provided 46 | true 47 | 48 | 49 | 50 | 51 | 52 | The Apache Software License, Version 2.0 53 | http://www.apache.org/licenses/LICENSE-2.0.txt 54 | 55 | 56 | 57 | 58 | zhongxun 59 | zhongxunking@163.com 60 | 61 | 62 | 63 | scm:git@github.com:zhongxunking/bekit.git 64 | scm:git@github.com:zhongxunking/bekit.git 65 | git@github.com:zhongxunking/bekit.git 66 | 67 | 68 | 69 | 70 | 71 | 72 | org.apache.maven.plugins 73 | maven-source-plugin 74 | 75 | 76 | package 77 | 78 | jar-no-fork 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | release-oss 89 | 90 | 91 | 92 | 93 | org.apache.maven.plugins 94 | maven-javadoc-plugin 95 | 96 | 97 | package 98 | 99 | jar 100 | 101 | 102 | 103 | 104 | 105 | 106 | org.apache.maven.plugins 107 | maven-gpg-plugin 108 | 1.6 109 | 110 | 111 | verify 112 | 113 | sign 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | oss 123 | https://oss.sonatype.org/content/repositories/snapshots/ 124 | 125 | 126 | oss 127 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /event/src/main/java/org/bekit/event/bus/EventBus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.event.bus; 10 | 11 | import lombok.RequiredArgsConstructor; 12 | import org.bekit.event.extension.EventTypeResolver; 13 | import org.bekit.event.listener.ListenerExecutor; 14 | import org.bekit.event.listener.PriorityType; 15 | 16 | import java.util.*; 17 | 18 | /** 19 | * 事件总线 20 | */ 21 | @RequiredArgsConstructor 22 | public class EventBus { 23 | // 事件类型解决器 24 | private final EventTypeResolver eventTypeResolver; 25 | // 所有监听器执行器 26 | private final Set listenerExecutors = new HashSet<>(); 27 | // 分发器 28 | private Dispatcher dispatcher = new Dispatcher(); 29 | 30 | /** 31 | * 分发事件 32 | * 33 | * @param event 事件 34 | * @throws Throwable 执行过程中发生任何异常都会往外抛 35 | */ 36 | public void dispatch(Object event) throws Throwable { 37 | dispatcher.dispatch(event); 38 | } 39 | 40 | /** 41 | * 添加监听器执行器 42 | * 43 | * @param listenerExecutor 监听器执行器 44 | */ 45 | public synchronized void addListenerExecutor(ListenerExecutor listenerExecutor) { 46 | if (!listenerExecutors.contains(listenerExecutor)) { 47 | listenerExecutors.add(listenerExecutor); 48 | dispatcher = dispatcher.addExecutor(listenerExecutor); 49 | } 50 | } 51 | 52 | /** 53 | * 移除监听器执行器 54 | * 55 | * @param listenerExecutor 监听器 56 | */ 57 | public synchronized void removeListenerExecutor(ListenerExecutor listenerExecutor) { 58 | if (listenerExecutors.contains(listenerExecutor)) { 59 | listenerExecutors.remove(listenerExecutor); 60 | dispatcher = dispatcher.removeExecutor(listenerExecutor); 61 | } 62 | } 63 | 64 | // 分发器 65 | private class Dispatcher { 66 | // 升序队列 67 | private final Map> asc = new HashMap<>(); 68 | // 降序队列 69 | private final Map> desc = new HashMap<>(); 70 | 71 | // 分发事件 72 | void dispatch(Object event) throws Throwable { 73 | Object eventType = eventTypeResolver.resolve(event); 74 | // 向升序队列分发事件 75 | doDispatch(asc.get(eventType), event); 76 | // 向降序队列分发事件 77 | doDispatch(desc.get(eventType), event); 78 | } 79 | 80 | // 执行分发事件 81 | private void doDispatch(List executors, Object event) throws Throwable { 82 | if (executors != null) { 83 | for (ListenerExecutor executor : executors) { 84 | executor.execute(event); 85 | } 86 | } 87 | } 88 | 89 | // 新增监听器执行器(返回新的分发器) 90 | Dispatcher addExecutor(ListenerExecutor executor) { 91 | Dispatcher nextDispatcher = copy(); 92 | // 调整升序队列 93 | doAddExecutor(nextDispatcher.asc, executor, PriorityType.ASC, Comparator.comparingInt(ListenerExecutor::getPriority)); 94 | // 调整降序队列 95 | doAddExecutor(nextDispatcher.desc, executor, PriorityType.DESC, (left, right) -> right.getPriority() - left.getPriority()); 96 | 97 | return nextDispatcher; 98 | } 99 | 100 | // 执行新增监听器执行器 101 | private void doAddExecutor(Map> executorsMap, ListenerExecutor executor, PriorityType priorityType, Comparator comparator) { 102 | for (Object eventType : executor.getEventTypes(priorityType)) { 103 | List executors = executorsMap.computeIfAbsent(eventType, k -> new ArrayList<>()); 104 | executors.add(executor); 105 | executors.sort(comparator); 106 | } 107 | } 108 | 109 | // 删除监听器执行器(返回新的分发器) 110 | Dispatcher removeExecutor(ListenerExecutor executor) { 111 | Dispatcher nextDispatcher = copy(); 112 | // 调整升序队列 113 | doRemoveExecutor(nextDispatcher.asc, executor, PriorityType.ASC); 114 | // 调整降序队列 115 | doRemoveExecutor(nextDispatcher.desc, executor, PriorityType.DESC); 116 | 117 | return nextDispatcher; 118 | } 119 | 120 | // 执行删除监听器执行器 121 | private void doRemoveExecutor(Map> executorsMap, ListenerExecutor executor, PriorityType priorityType) { 122 | for (Object eventType : executor.getEventTypes(priorityType)) { 123 | executorsMap.computeIfPresent(eventType, (k, executors) -> { 124 | executors.remove(executor); 125 | if (executors.isEmpty()) { 126 | executors = null; 127 | } 128 | return executors; 129 | }); 130 | } 131 | } 132 | 133 | // 深度复制 134 | private Dispatcher copy() { 135 | Dispatcher newDispatcher = new Dispatcher(); 136 | doCopy(asc, newDispatcher.asc); 137 | doCopy(desc, newDispatcher.desc); 138 | return newDispatcher; 139 | } 140 | 141 | // 执行深度复制 142 | private void doCopy(Map> source, Map> target) { 143 | source.forEach((eventType, executors) -> { 144 | List newExecutors = new ArrayList<>(executors.size() + 1); 145 | newExecutors.addAll(executors); 146 | target.put(eventType, newExecutors); 147 | }); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /service/src/main/java/org/bekit/service/service/ServiceParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-16 01:14 创建 8 | */ 9 | package org.bekit.service.service; 10 | 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.apache.commons.lang3.StringUtils; 13 | import org.bekit.common.transaction.TransactionManager; 14 | import org.bekit.common.transaction.TxExecutor; 15 | import org.bekit.event.bus.EventBusHub; 16 | import org.bekit.event.publisher.DefaultEventPublisher; 17 | import org.bekit.service.annotation.service.Service; 18 | import org.bekit.service.annotation.service.ServiceAfter; 19 | import org.bekit.service.annotation.service.ServiceBefore; 20 | import org.bekit.service.annotation.service.ServiceExecute; 21 | import org.bekit.service.engine.ServiceContext; 22 | import org.bekit.service.listener.ServiceListenerType; 23 | import org.bekit.service.service.ServiceExecutor.ServicePhaseExecutor; 24 | import org.springframework.aop.support.AopUtils; 25 | import org.springframework.core.ResolvableType; 26 | import org.springframework.core.annotation.AnnotatedElementUtils; 27 | import org.springframework.util.Assert; 28 | import org.springframework.util.ClassUtils; 29 | import org.springframework.util.ReflectionUtils; 30 | 31 | import java.lang.annotation.Annotation; 32 | import java.lang.reflect.Method; 33 | import java.lang.reflect.Modifier; 34 | import java.util.HashMap; 35 | import java.util.Map; 36 | 37 | /** 38 | * 服务解析器 39 | */ 40 | @Slf4j 41 | public final class ServiceParser { 42 | // 服务阶段注解 43 | private static final Class[] SERVICE_PHASE_ANNOTATIONS = new Class[]{ServiceBefore.class, ServiceExecute.class, ServiceAfter.class}; 44 | 45 | /** 46 | * 解析服务 47 | * 48 | * @param service 服务 49 | * @param eventBusHub 事件总线中心 50 | * @param transactionManager 事务管理器 51 | * @return 服务执行器 52 | */ 53 | public static ServiceExecutor parseService(Object service, 54 | EventBusHub eventBusHub, 55 | TransactionManager transactionManager) { 56 | // 获取目标class(应对AOP代理情况) 57 | Class serviceClass = AopUtils.getTargetClass(service); 58 | log.debug("解析服务:{}", serviceClass); 59 | Service serviceAnnotation = AnnotatedElementUtils.findMergedAnnotation(serviceClass, Service.class); 60 | // 获取服务名称 61 | String serviceName = serviceAnnotation.name(); 62 | if (StringUtils.isEmpty(serviceName)) { 63 | serviceName = ClassUtils.getShortNameAsProperty(serviceClass); 64 | } 65 | // 计算事务执行器 66 | TxExecutor txExecutor = null; 67 | if (serviceAnnotation.enableTx()) { 68 | txExecutor = new TxExecutor(transactionManager, TransactionManager.TransactionType.REQUIRED); 69 | } 70 | // 解析出所有服务阶段 71 | Map, ServicePhaseExecutor> phaseExecutorMap = parseToPhaseExecutors(serviceClass); 72 | 73 | return new ServiceExecutor( 74 | serviceName, 75 | service, 76 | phaseExecutorMap, 77 | new DefaultEventPublisher(eventBusHub.getEventBus(ServiceListenerType.class)), 78 | txExecutor); 79 | } 80 | 81 | // 解析出所有服务阶段 82 | private static Map, ServicePhaseExecutor> parseToPhaseExecutors(Class serviceClass) { 83 | Map, ServicePhaseExecutor> map = new HashMap<>(); 84 | // 解析 85 | ReflectionUtils.doWithLocalMethods(serviceClass, method -> { 86 | for (Class annotationClass : SERVICE_PHASE_ANNOTATIONS) { 87 | Annotation annotation = AnnotatedElementUtils.findMergedAnnotation(method, annotationClass); 88 | if (annotation != null) { 89 | map.put(annotationClass, parseServicePhase(method)); 90 | } 91 | } 92 | }); 93 | // 校验 94 | Assert.isTrue(map.containsKey(ServiceExecute.class), String.format("服务[%s]缺少@ServiceExecute类型方法", serviceClass)); 95 | Class orderType = map.get(ServiceExecute.class).getOrderType(); 96 | Class resultType = map.get(ServiceExecute.class).getResultType(); 97 | Assert.isTrue(ClassUtils.hasConstructor(resultType), String.format("@ServiceExecute服务方法[%s]的参数ServiceContext的泛型[%s]必须得有默认构造函数", map.get(ServiceExecute.class).getMethod(), resultType)); 98 | map.forEach((annotationClass, phaseExecutor) -> { 99 | Assert.isAssignable(phaseExecutor.getOrderType(), orderType, String.format("服务[%s]内的ServiceContext的泛型类型不统一", serviceClass)); 100 | Assert.isAssignable(phaseExecutor.getResultType(), resultType, String.format("服务[%s]内的ServiceContext的泛型类型不统一", serviceClass)); 101 | }); 102 | 103 | return map; 104 | } 105 | 106 | // 解析服务阶段方法 107 | private static ServicePhaseExecutor parseServicePhase(Method servicePhaseMethod) { 108 | log.debug("解析服务方法:{}", servicePhaseMethod); 109 | // 校验方法类型、返回类型 110 | Assert.isTrue(Modifier.isPublic(servicePhaseMethod.getModifiers()), String.format("服务方法[%s]必须是public类型", servicePhaseMethod)); 111 | Assert.isTrue(servicePhaseMethod.getReturnType() == void.class, String.format("服务方法[%s]的返回类型必须是void", servicePhaseMethod)); 112 | // 校验入参类型 113 | Class[] parameterTypes = servicePhaseMethod.getParameterTypes(); 114 | if (parameterTypes.length != 1 || parameterTypes[0] != ServiceContext.class) { 115 | throw new IllegalArgumentException(String.format("服务方法[%s]的入参必须是(ServiceContext context)", servicePhaseMethod)); 116 | } 117 | // 获取ServiceContext中泛型O、R的真实类型 118 | ResolvableType resolvableType = ResolvableType.forMethodParameter(servicePhaseMethod, 0); 119 | Class orderType = resolvableType.getGeneric(0).resolve(Object.class); 120 | Class resultType = resolvableType.getGeneric(1).resolve(Object.class); 121 | 122 | return new ServicePhaseExecutor(servicePhaseMethod, orderType, resultType); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/boot/FlowEngineConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-23 20:55 创建 8 | */ 9 | package org.bekit.flow.boot; 10 | 11 | import org.bekit.common.scanner.AbstractScanner; 12 | import org.bekit.common.transaction.TransactionManager; 13 | import org.bekit.event.boot.EventBusConfiguration; 14 | import org.bekit.event.bus.EventBusHub; 15 | import org.bekit.flow.annotation.flow.Flow; 16 | import org.bekit.flow.annotation.locker.TheFlowLocker; 17 | import org.bekit.flow.annotation.mapper.TheFlowMapper; 18 | import org.bekit.flow.annotation.processor.Processor; 19 | import org.bekit.flow.engine.DefaultFlowEngine; 20 | import org.bekit.flow.flow.FlowExecutor; 21 | import org.bekit.flow.flow.FlowParser; 22 | import org.bekit.flow.flow.FlowRegistrar; 23 | import org.bekit.flow.listener.DefaultFlowListener; 24 | import org.bekit.flow.locker.TheFlowLockerExecutor; 25 | import org.bekit.flow.locker.TheFlowLockerParser; 26 | import org.bekit.flow.locker.TheFlowLockerRegistrar; 27 | import org.bekit.flow.mapper.TheFlowMapperExecutor; 28 | import org.bekit.flow.mapper.TheFlowMapperParser; 29 | import org.bekit.flow.mapper.TheFlowMapperRegistrar; 30 | import org.bekit.flow.processor.ProcessorExecutor; 31 | import org.bekit.flow.processor.ProcessorParser; 32 | import org.bekit.flow.processor.ProcessorRegistrar; 33 | import org.springframework.context.annotation.Configuration; 34 | import org.springframework.context.annotation.Import; 35 | import org.springframework.core.annotation.Order; 36 | import org.springframework.util.Assert; 37 | 38 | /** 39 | * 流程引擎配置 40 | */ 41 | @Configuration 42 | @Import({EventBusConfiguration.class, 43 | DefaultFlowEngine.class, 44 | DefaultFlowListener.class, 45 | ProcessorRegistrar.class, 46 | TheFlowMapperRegistrar.class, 47 | TheFlowLockerRegistrar.class, 48 | FlowRegistrar.class, 49 | FlowEngineConfiguration.ProcessorScanner.class, 50 | FlowEngineConfiguration.TheFlowMapperScanner.class, 51 | FlowEngineConfiguration.TheFlowLockerScanner.class, 52 | FlowEngineConfiguration.FlowScanner.class}) 53 | public class FlowEngineConfiguration { 54 | /** 55 | * 优先级 56 | */ 57 | public static final int ORDER = 1000; 58 | 59 | /** 60 | * 处理器扫描器 61 | */ 62 | @Order(ORDER) 63 | public static class ProcessorScanner extends AbstractScanner { 64 | // 处理器注册器 65 | private final ProcessorRegistrar processorRegistrar; 66 | 67 | public ProcessorScanner(ProcessorRegistrar processorRegistrar) { 68 | super(Processor.class); 69 | this.processorRegistrar = processorRegistrar; 70 | } 71 | 72 | @Override 73 | protected void onScan(Object obj) { 74 | // 解析 75 | ProcessorExecutor processorExecutor = ProcessorParser.parseProcessor(obj); 76 | // 注册 77 | ProcessorExecutor existedOne = processorRegistrar.register(processorExecutor); 78 | Assert.isNull(existedOne, String.format("存在重名的处理器[%s]", processorExecutor.getProcessorName())); 79 | } 80 | } 81 | 82 | /** 83 | * 特定流程映射器扫描器 84 | */ 85 | @Order(ORDER + 100) 86 | public static class TheFlowMapperScanner extends AbstractScanner { 87 | // 处理器注册器 88 | private final TheFlowMapperRegistrar theFlowMapperRegistrar; 89 | 90 | public TheFlowMapperScanner(TheFlowMapperRegistrar theFlowMapperRegistrar) { 91 | super(TheFlowMapper.class); 92 | this.theFlowMapperRegistrar = theFlowMapperRegistrar; 93 | } 94 | 95 | @Override 96 | protected void onScan(Object obj) { 97 | // 解析 98 | TheFlowMapperExecutor theFlowMapperExecutor = TheFlowMapperParser.parseTheFlowMapper(obj); 99 | // 注册 100 | TheFlowMapperExecutor existedOne = theFlowMapperRegistrar.register(theFlowMapperExecutor); 101 | Assert.isNull(existedOne, String.format("流程[%s]存在重复的特定流程映射器", theFlowMapperExecutor.getFlow())); 102 | } 103 | } 104 | 105 | /** 106 | * 特定流程加锁器扫描器 107 | */ 108 | @Order(ORDER + 200) 109 | public static class TheFlowLockerScanner extends AbstractScanner { 110 | // 处理器注册器 111 | private final TheFlowLockerRegistrar theFlowLockerRegistrar; 112 | 113 | public TheFlowLockerScanner(TheFlowLockerRegistrar theFlowLockerRegistrar) { 114 | super(TheFlowLocker.class); 115 | this.theFlowLockerRegistrar = theFlowLockerRegistrar; 116 | } 117 | 118 | @Override 119 | protected void onScan(Object obj) { 120 | // 解析 121 | TheFlowLockerExecutor theFlowLockerExecutor = TheFlowLockerParser.parseTheFlowLocker(obj); 122 | // 注册 123 | TheFlowLockerExecutor existedOne = theFlowLockerRegistrar.register(theFlowLockerExecutor); 124 | Assert.isNull(existedOne, String.format("流程[%s]存在重复的特定流程加锁器", theFlowLockerExecutor.getFlow())); 125 | } 126 | } 127 | 128 | 129 | /** 130 | * 流程扫描器 131 | */ 132 | @Order(ORDER + 300) 133 | public static class FlowScanner extends AbstractScanner { 134 | // 流程注册器 135 | private final FlowRegistrar flowRegistrar; 136 | // 处理器注册器 137 | private final ProcessorRegistrar processorRegistrar; 138 | // 特定流程映射器注册器 139 | private final TheFlowMapperRegistrar theFlowMapperRegistrar; 140 | // 特定流程加锁器注册器 141 | private final TheFlowLockerRegistrar theFlowLockerRegistrar; 142 | // 事务管理器 143 | private final TransactionManager transactionManager; 144 | // 事件总线中心 145 | private final EventBusHub eventBusHub; 146 | 147 | public FlowScanner(FlowRegistrar flowRegistrar, 148 | ProcessorRegistrar processorRegistrar, 149 | TheFlowMapperRegistrar theFlowMapperRegistrar, 150 | TheFlowLockerRegistrar theFlowLockerRegistrar, 151 | TransactionManager transactionManager, 152 | EventBusHub eventBusHub) { 153 | super(Flow.class); 154 | this.flowRegistrar = flowRegistrar; 155 | this.processorRegistrar = processorRegistrar; 156 | this.theFlowMapperRegistrar = theFlowMapperRegistrar; 157 | this.theFlowLockerRegistrar = theFlowLockerRegistrar; 158 | this.transactionManager = transactionManager; 159 | this.eventBusHub = eventBusHub; 160 | } 161 | 162 | @Override 163 | protected void onScan(Object obj) { 164 | // 解析 165 | FlowExecutor flowExecutor = FlowParser.parseFlow( 166 | obj, 167 | processorRegistrar, 168 | theFlowMapperRegistrar, 169 | theFlowLockerRegistrar, 170 | transactionManager, 171 | eventBusHub); 172 | // 注册 173 | FlowExecutor existedOne = flowRegistrar.register(flowExecutor); 174 | Assert.isNull(existedOne, String.format("存在重名的流程[%s]", flowExecutor.getFlowName())); 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/flow/FlowParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-19 01:40 创建 8 | */ 9 | package org.bekit.flow.flow; 10 | 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.apache.commons.lang3.StringUtils; 13 | import org.bekit.common.transaction.TransactionManager; 14 | import org.bekit.common.transaction.TxExecutor; 15 | import org.bekit.event.bus.EventBusHub; 16 | import org.bekit.event.publisher.DefaultEventPublisher; 17 | import org.bekit.flow.annotation.flow.EndNode; 18 | import org.bekit.flow.annotation.flow.Flow; 19 | import org.bekit.flow.annotation.flow.Node; 20 | import org.bekit.flow.annotation.flow.StartNode; 21 | import org.bekit.flow.engine.FlowContext; 22 | import org.bekit.flow.listener.FlowListenerType; 23 | import org.bekit.flow.locker.TheFlowLockerRegistrar; 24 | import org.bekit.flow.mapper.TheFlowMapperRegistrar; 25 | import org.bekit.flow.processor.ProcessorExecutor; 26 | import org.bekit.flow.processor.ProcessorRegistrar; 27 | import org.springframework.aop.support.AopUtils; 28 | import org.springframework.core.annotation.AnnotatedElementUtils; 29 | import org.springframework.util.Assert; 30 | import org.springframework.util.ClassUtils; 31 | import org.springframework.util.ReflectionUtils; 32 | 33 | import java.lang.reflect.Method; 34 | import java.lang.reflect.Modifier; 35 | import java.util.HashMap; 36 | import java.util.Map; 37 | 38 | /** 39 | * 流程解析器 40 | */ 41 | @Slf4j 42 | public class FlowParser { 43 | /** 44 | * 解析流程 45 | * 46 | * @param flow 流程 47 | * @param processorRegistrar 处理器注册器 48 | * @param mapperRegistrar 映射器注册器 49 | * @param lockerRegistrar 加锁器注册器 50 | * @param transactionManager 事务管理器 51 | * @param eventBusHub 事件总线中心 52 | * @return 流程执行器 53 | */ 54 | public static FlowExecutor parseFlow(Object flow, 55 | ProcessorRegistrar processorRegistrar, 56 | TheFlowMapperRegistrar mapperRegistrar, 57 | TheFlowLockerRegistrar lockerRegistrar, 58 | TransactionManager transactionManager, 59 | EventBusHub eventBusHub) { 60 | // 获取目标class(应对AOP代理情况) 61 | Class flowClass = AopUtils.getTargetClass(flow); 62 | log.debug("解析流程:{}", flowClass); 63 | // 解析流程名称 64 | Flow flowAnnotation = AnnotatedElementUtils.findMergedAnnotation(flowClass, Flow.class); 65 | String flowName = flowAnnotation.name(); 66 | if (StringUtils.isEmpty(flowName)) { 67 | flowName = ClassUtils.getShortNameAsProperty(flowClass); 68 | } 69 | // 解析出所有节点执行器 70 | Map, Map> map = parseToNodeExecutors(flowClass, processorRegistrar); 71 | 72 | return new FlowExecutor( 73 | flowName, 74 | flow, 75 | map.get(StartNode.class).keySet().iterator().next(), 76 | map.get(EndNode.class).keySet(), 77 | map.get(Node.class), 78 | mapperRegistrar.get(flowName), 79 | lockerRegistrar.get(flowName), 80 | new TxExecutor(transactionManager, TransactionManager.TransactionType.REQUIRED), 81 | new DefaultEventPublisher(eventBusHub.getEventBus(FlowListenerType.class))); 82 | } 83 | 84 | // 解析出所有节点执行器 85 | private static Map, Map> parseToNodeExecutors(Class flowClass, ProcessorRegistrar processorRegistrar) { 86 | Map, Map> map = new HashMap<>(); 87 | map.put(Node.class, new HashMap<>()); 88 | map.put(StartNode.class, new HashMap<>()); 89 | map.put(EndNode.class, new HashMap<>()); 90 | // 解析 91 | ReflectionUtils.doWithLocalMethods(flowClass, method -> { 92 | Node nodeAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, Node.class); 93 | if (nodeAnnotation != null) { 94 | FlowExecutor.NodeExecutor nodeExecutor = parseNode(nodeAnnotation, method, processorRegistrar); 95 | Map nodeExecutorMap = map.get(Node.class); 96 | Assert.isTrue(!nodeExecutorMap.containsKey(nodeExecutor.getNodeName()), String.format("流程[%s]存在重名的节点[%s]", flowClass, nodeExecutor.getNodeName())); 97 | nodeExecutorMap.put(nodeExecutor.getNodeName(), nodeExecutor); 98 | // 判断是否是@StartNode、@EndNode 99 | if (AnnotatedElementUtils.findMergedAnnotation(method, StartNode.class) != null) { 100 | map.get(StartNode.class).put(nodeExecutor.getNodeName(), nodeExecutor); 101 | } else if (AnnotatedElementUtils.findMergedAnnotation(method, EndNode.class) != null) { 102 | map.get(EndNode.class).put(nodeExecutor.getNodeName(), nodeExecutor); 103 | } 104 | } 105 | }); 106 | Assert.isTrue(map.get(StartNode.class).size() == 1, String.format("流程[%s]必须存在唯一的一个开始节点(@StartNode)", flowClass)); 107 | 108 | return map; 109 | } 110 | 111 | // 解析节点 112 | private static FlowExecutor.NodeExecutor parseNode(Node nodeAnnotation, Method nodeMethod, ProcessorRegistrar processorRegistrar) { 113 | log.debug("解析流程节点:node={},method={}", nodeAnnotation, nodeMethod); 114 | // 获取节点名称 115 | String nodeName = nodeAnnotation.name(); 116 | if (StringUtils.isEmpty(nodeName)) { 117 | nodeName = nodeMethod.getName(); 118 | } 119 | // 获取处理器 120 | ProcessorExecutor processorExecutor = null; 121 | if (StringUtils.isNotEmpty(nodeAnnotation.processor())) { 122 | processorExecutor = processorRegistrar.get(nodeAnnotation.processor()); 123 | Assert.notNull(processorExecutor, String.format("不存在处理器[%s]", processorExecutor.getProcessorName())); 124 | } 125 | // 解析节点决策器 126 | FlowExecutor.NodeExecutor.NodeDeciderExecutor nodeDeciderExecutor = parseNodeDecider(nodeMethod, processorExecutor); 127 | 128 | return new FlowExecutor.NodeExecutor( 129 | nodeName, 130 | nodeAnnotation.haveState(), 131 | nodeAnnotation.autoExecute(), 132 | processorExecutor, 133 | nodeDeciderExecutor); 134 | } 135 | 136 | // 解析节点决策器 137 | private static FlowExecutor.NodeExecutor.NodeDeciderExecutor parseNodeDecider(Method nodeDeciderMethod, ProcessorExecutor processorExecutor) { 138 | // 校验方法类型 139 | Assert.isTrue(Modifier.isPublic(nodeDeciderMethod.getModifiers()), String.format("节点决策器[%s]必须是public类型", nodeDeciderMethod)); 140 | // 判断+校验入参类型,可以存在的入参类型:()、(FlowContext)、(T)、(T, FlowContext)————T表示能被处理器返回结果赋值的类型 141 | FlowExecutor.NodeExecutor.NodeDeciderExecutor.ParameterType parameterType; 142 | Class[] parameterTypes = nodeDeciderMethod.getParameterTypes(); 143 | if (parameterTypes.length == 0) { 144 | // 入参类型:() 145 | parameterType = FlowExecutor.NodeExecutor.NodeDeciderExecutor.ParameterType.NONE; 146 | } else { 147 | Assert.isTrue(AnnotatedElementUtils.findMergedAnnotation(nodeDeciderMethod, EndNode.class) == null, String.format("结束节点的决策器[%s]的入参类型必须为()", nodeDeciderMethod)); 148 | if (parameterTypes.length == 1) { 149 | if (parameterTypes[0] == FlowContext.class) { 150 | // 入参类型:(FlowContext) 151 | parameterType = FlowExecutor.NodeExecutor.NodeDeciderExecutor.ParameterType.ONLY_FLOW_CONTEXT; 152 | } else { 153 | // 入参类型:(T) 154 | Assert.isTrue(processorExecutor != null, String.format("节点决策器[%s]不能有非FlowContext入参,因为这个节点没有处理器", nodeDeciderMethod)); 155 | Assert.isAssignable(parameterTypes[0], processorExecutor.getReturnType(), String.format("节点决策器[%s]的入参类型必须能被其处理器返回类型赋值", nodeDeciderMethod)); 156 | parameterType = FlowExecutor.NodeExecutor.NodeDeciderExecutor.ParameterType.ONLY_PROCESS_RESULT; 157 | } 158 | } else if (parameterTypes.length == 2) { 159 | // 入参类型:(T, FlowContext) 160 | Assert.isTrue(processorExecutor != null, String.format("节点决策器[%s]不能有非FlowContext入参,因为这个节点没有处理器", nodeDeciderMethod)); 161 | Assert.isAssignable(parameterTypes[0], processorExecutor.getReturnType(), String.format("节点决策器[%s]的第一个入参类型必须能被其处理器返回类型赋值", nodeDeciderMethod)); 162 | Assert.isTrue(parameterTypes[1] == FlowContext.class, String.format("节点决策器[%s]的第二个入参类型必须是FlowContext", nodeDeciderMethod)); 163 | parameterType = FlowExecutor.NodeExecutor.NodeDeciderExecutor.ParameterType.PROCESS_RESULT_AND_FLOW_CONTEXT; 164 | } else { 165 | throw new IllegalArgumentException(String.format("节点决策器[%s]的入参类型必须为:()、(FlowContext)、(T)、(T, FlowContext)————T表示能被处理器返回结果赋值的类型", nodeDeciderMethod)); 166 | } 167 | } 168 | // 校验返回类型 169 | if (AnnotatedElementUtils.findMergedAnnotation(nodeDeciderMethod, EndNode.class) == null) { 170 | Assert.isTrue(nodeDeciderMethod.getReturnType() == String.class, String.format("节点决策器[%s]的返回类型必须是String", nodeDeciderMethod)); 171 | } else { 172 | Assert.isTrue(nodeDeciderMethod.getReturnType() == void.class, String.format("结束节点(@EndNode)的决策器[%s]的返回类型必须是void", nodeDeciderMethod)); 173 | } 174 | 175 | return new FlowExecutor.NodeExecutor.NodeDeciderExecutor(parameterType, nodeDeciderMethod); 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /flow/src/main/java/org/bekit/flow/flow/FlowExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 作者:钟勋 (e-mail:zhongxunking@163.com) 3 | */ 4 | 5 | /* 6 | * 修订记录: 7 | * @author 钟勋 2016-12-18 23:48 创建 8 | */ 9 | package org.bekit.flow.flow; 10 | 11 | import lombok.AllArgsConstructor; 12 | import lombok.Getter; 13 | import org.bekit.common.method.MethodExecutor; 14 | import org.bekit.common.transaction.TxExecutor; 15 | import org.bekit.event.EventPublisher; 16 | import org.bekit.flow.annotation.locker.FlowLock; 17 | import org.bekit.flow.annotation.locker.FlowUnlock; 18 | import org.bekit.flow.annotation.locker.StateLock; 19 | import org.bekit.flow.annotation.locker.StateUnlock; 20 | import org.bekit.flow.engine.FlowContext; 21 | import org.bekit.flow.event.*; 22 | import org.bekit.flow.locker.TheFlowLockerExecutor; 23 | import org.bekit.flow.mapper.TheFlowMapperExecutor; 24 | import org.bekit.flow.processor.ProcessorExecutor; 25 | 26 | import java.lang.reflect.Method; 27 | import java.util.Map; 28 | import java.util.Set; 29 | 30 | /** 31 | * 流程执行器 32 | */ 33 | @AllArgsConstructor 34 | public class FlowExecutor { 35 | // 流程名称 36 | @Getter 37 | private final String flowName; 38 | // 流程 39 | @Getter 40 | private final Object flow; 41 | // 开始节点 42 | private final String startNode; 43 | // 结束节点 44 | private final Set endNodes; 45 | // 节点执行器Map(key:节点名称) 46 | private final Map nodeExecutorMap; 47 | // 映射器执行器 48 | private final TheFlowMapperExecutor mapperExecutor; 49 | // 加锁器执行器 50 | private final TheFlowLockerExecutor lockerExecutor; 51 | // 事务执行器 52 | private final TxExecutor txExecutor; 53 | // 事件发布器 54 | private final EventPublisher eventPublisher; 55 | 56 | /** 57 | * 执行 58 | * 59 | * @param context 流程上下文 60 | * @throws Throwable 执行过程中发生任何异常都会往外抛 61 | */ 62 | public void execute(FlowContext context) throws Throwable { 63 | try { 64 | // 发布流程开始事件 65 | eventPublisher.publish(new FlowStartEvent(flowName, context)); 66 | // 映射出节点 67 | String node = mappingNode(context, startNode); 68 | try { 69 | // 流程前置处理 70 | node = beforeFlow(context, node); 71 | try { 72 | // 状态前置处理 73 | node = beforeState(context, node); 74 | if (!endNodes.contains(node)) { 75 | // 获取节点执行器 76 | NodeExecutor nodeExecutor = getRequiredNodeExecutor(node); 77 | do { 78 | // 发布正在执行的节点事件 79 | eventPublisher.publish(new ExecutingNodeEvent(flowName, node, context)); 80 | // 执行节点 81 | node = nodeExecutor.execute(flow, context); 82 | // 是否中断流程 83 | if (node == null) { 84 | break; 85 | } 86 | // 获取下个节点执行器 87 | nodeExecutor = getRequiredNodeExecutor(node); 88 | // 发布节点选择事件 89 | eventPublisher.publish(new DecidedNodeEvent(flowName, node, context)); 90 | // 下个节点是否是状态节点 91 | if (nodeExecutor.isHaveState()) { 92 | // 发布状态节点选择事件 93 | eventPublisher.publish(new DecidedStateNodeEvent(flowName, node, context)); 94 | // 下个节点是否自动执行 95 | if (nodeExecutor.isAutoExecute()) { 96 | afterState(context); 97 | // 刷新下个节点(防止状态锁解锁后目标对象被其他线程抢占并执行到其他节点,此处更新到最新节点) 98 | node = beforeState(context, node); 99 | nodeExecutor = getRequiredNodeExecutor(node); 100 | } 101 | } 102 | } while (nodeExecutor.isAutoExecute()); 103 | } 104 | // 状态后置处理 105 | afterState(context); 106 | } catch (Throwable e) { 107 | // 状态异常处理 108 | afterStateException(context); 109 | throw e; 110 | } 111 | } finally { 112 | // 流程后置处理 113 | afterFlow(context); 114 | } 115 | } catch (Throwable e) { 116 | // 发布流程异常事件 117 | eventPublisher.publish(new FlowExceptionEvent(flowName, e, context)); 118 | throw e; 119 | } finally { 120 | // 发布流程结束事件 121 | eventPublisher.publish(new FlowEndEvent(flowName, context)); 122 | } 123 | } 124 | 125 | // 映射出节点 126 | private String mappingNode(FlowContext context, String defaultNode) throws Throwable { 127 | String node = defaultNode; 128 | if (mapperExecutor != null) { 129 | node = mapperExecutor.execute(context); 130 | } 131 | return node; 132 | } 133 | 134 | // 流程前置处理 135 | private String beforeFlow(FlowContext context, String defaultNode) throws Throwable { 136 | String node = defaultNode; 137 | if (lockerExecutor != null && lockerExecutor.contain(FlowLock.class)) { 138 | Object newTarget = lockerExecutor.execute(FlowLock.class, context); 139 | ((FlowContext) context).refreshTarget(newTarget); 140 | node = mappingNode(context, node); 141 | } 142 | return node; 143 | } 144 | 145 | // 状态前置处理 146 | private String beforeState(FlowContext context, String defaultNode) throws Throwable { 147 | String node = defaultNode; 148 | txExecutor.createTx(); 149 | if (lockerExecutor != null && lockerExecutor.contain(StateLock.class)) { 150 | Object newTarget = lockerExecutor.execute(StateLock.class, context); 151 | ((FlowContext) context).refreshTarget(newTarget); 152 | node = mappingNode(context, node); 153 | } 154 | return node; 155 | } 156 | 157 | // 获取节点执行器 158 | private NodeExecutor getRequiredNodeExecutor(String node) { 159 | NodeExecutor nodeExecutor = nodeExecutorMap.get(node); 160 | if (nodeExecutor == null) { 161 | throw new IllegalStateException(String.format("流程[%s]不存在节点[%s]", flowName, node)); 162 | } 163 | return nodeExecutor; 164 | } 165 | 166 | // 状态后置处理 167 | private void afterState(FlowContext context) throws Throwable { 168 | if (lockerExecutor != null && lockerExecutor.contain(StateUnlock.class)) { 169 | lockerExecutor.execute(StateUnlock.class, context); 170 | } 171 | txExecutor.commitTx(); 172 | } 173 | 174 | // 状态异常处理 175 | private void afterStateException(FlowContext context) throws Throwable { 176 | try { 177 | if (lockerExecutor != null && lockerExecutor.contain(StateUnlock.class)) { 178 | lockerExecutor.execute(StateUnlock.class, context); 179 | } 180 | } finally { 181 | txExecutor.rollbackTx(); 182 | } 183 | } 184 | 185 | // 流程后置处理 186 | private void afterFlow(FlowContext context) throws Throwable { 187 | if (lockerExecutor != null && lockerExecutor.contain(FlowUnlock.class)) { 188 | lockerExecutor.execute(FlowUnlock.class, context); 189 | } 190 | } 191 | 192 | /** 193 | * 节点执行器 194 | */ 195 | @AllArgsConstructor 196 | public static class NodeExecutor { 197 | // 节点名称 198 | @Getter 199 | private final String nodeName; 200 | // 是否有状态 201 | @Getter 202 | private final boolean haveState; 203 | // 是否自动执行 204 | @Getter 205 | private final boolean autoExecute; 206 | // 处理器执行器 207 | private final ProcessorExecutor processorExecutor; 208 | // 节点决策器执行器 209 | private final NodeDeciderExecutor nodeDeciderExecutor; 210 | 211 | /** 212 | * 执行 213 | * 214 | * @param flow 流程 215 | * @param context 流程上下文 216 | * @return 下个节点 217 | * @throws Throwable 执行过程中发生任何异常都会往外抛 218 | */ 219 | public String execute(Object flow, FlowContext context) throws Throwable { 220 | Object processResult = null; 221 | if (processorExecutor != null) { 222 | // 执行节点处理器 223 | processResult = processorExecutor.execute(context); 224 | } 225 | // 执行节点决策器 226 | return nodeDeciderExecutor.execute(flow, processResult, context); 227 | } 228 | 229 | /** 230 | * 节点决策器执行器 231 | */ 232 | public static class NodeDeciderExecutor extends MethodExecutor { 233 | // 参数类型 234 | private final ParameterType parameterType; 235 | 236 | public NodeDeciderExecutor(ParameterType parameterType, Method nodeDeciderMethod) { 237 | super(nodeDeciderMethod); 238 | this.parameterType = parameterType; 239 | } 240 | 241 | /** 242 | * 执行 243 | * 244 | * @param flow 流程 245 | * @param processResult 处理器执行结果 246 | * @param context 流程上下文 247 | * @return 下个节点名称 248 | * @throws Throwable 执行过程中发生任何异常都会往外抛 249 | */ 250 | public String execute(Object flow, Object processResult, FlowContext context) throws Throwable { 251 | switch (parameterType) { 252 | case NONE: 253 | return (String) execute(flow, new Object[]{}); 254 | case ONLY_PROCESS_RESULT: 255 | return (String) execute(flow, new Object[]{processResult}); 256 | case ONLY_FLOW_CONTEXT: 257 | return (String) execute(flow, new Object[]{context}); 258 | case PROCESS_RESULT_AND_FLOW_CONTEXT: 259 | return (String) execute(flow, new Object[]{processResult, context}); 260 | default: 261 | throw new IllegalStateException("节点决策器执行器内部要素不对"); 262 | } 263 | } 264 | 265 | /** 266 | * 节点决策器方法参数类型 267 | */ 268 | public enum ParameterType { 269 | /** 270 | * 无参数 271 | */ 272 | NONE, 273 | /** 274 | * 只有处理结果参数 275 | */ 276 | ONLY_PROCESS_RESULT, 277 | /** 278 | * 只有流程上下文 279 | */ 280 | ONLY_FLOW_CONTEXT, 281 | /** 282 | * 处理结果和流程上下文都有 283 | */ 284 | PROCESS_RESULT_AND_FLOW_CONTEXT,; 285 | } 286 | } 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------