Activiti执行Command
简化版的执行Activiti Command。
一、类图
1、Command
- Command
public interface Command<T> {
T execute(CommandContext commandContext);
}
- DoSomethingCmd
public class DoSomethingCmd implements Command<Void>{
public Void execute(CommandContext commandContext) {
System.out.println("do something...");
return null;
}
}
2、CommandInterceptor
- CommandInterceptor
public interface CommandInterceptor {
<T> T execute(CommandConfig config, Command<T> command);
CommandInterceptor getNext();
void setNext(CommandInterceptor next);
}
- AbstractCommandInterceptor
public abstract class AbstractCommandInterceptor implements CommandInterceptor{
protected CommandInterceptor next;
public CommandInterceptor getNext() {
return this.next;
}
public void setNext(CommandInterceptor next) {
this.next = next;
}
}
- LogInterceptor
public class LogInterceptor extends AbstractCommandInterceptor{
public <T> T execute(CommandConfig config, Command<T> command) {
try{
System.out.println("start...");
return next.execute(config, command);
}finally{
System.out.println("finish...");
}
}
}
- CommandContextInterceptor
public class CommandContextInterceptor extends AbstractCommandInterceptor{
protected CommandContextFactory contextFactory;
protected EngineConfiguration engineConfiguration;
public CommandContextInterceptor(CommandContextFactory contextFactory, EngineConfiguration engineConfiguration) {
this.contextFactory = contextFactory;
this.engineConfiguration = engineConfiguration;
}
public <T> T execute(CommandConfig config, Command<T> command) {
CommandContext context = Context.getCommandContext();
boolean contextReused = false;
if(!config.isReuse() || context == null){
context = contextFactory.createCommandContext(command);
}else{
contextReused = true;
context.setResult(true);
}
try{
Context.setCommandContext(context);
Context.setEngineConfiguration(engineConfiguration);
return next.execute(config, command);
}catch(Exception e){
e.printStackTrace();
}finally{
if(!contextReused){
context.close();
}
Context.removeCommandContext();
Context.removeEngineConfiguration();
}
return null;
}
}
- CommandInvoker
public class CommandInvoker extends AbstractCommandInterceptor{
@SuppressWarnings("unchecked")
public <T> T execute(final CommandConfig config, final Command<T> command) {
final CommandContext commandContext = Context.getCommandContext();
commandContext.getAgenda().planOperation(new Runnable() {
public void run() {
commandContext.setResult(command.execute(commandContext));
}
});
executeOperations(commandContext);
return (T) commandContext.getResult();
}
protected void executeOperations(final CommandContext commandContext){
ActivitiAgenda agenda = commandContext.getAgenda();
while(!agenda.isEmpty()){
Runnable runnable = agenda.getNextOperation();
executeOperation(runnable);
}
}
public void executeOperation(Runnable runnable) {
runnable.run();
}
}
3、Agenda
- Agenda
public interface Agenda {
boolean isEmpty();
Runnable getNextOperation();
void planOperation(Runnable operation);
}
- ActivitiAgenda
public interface ActivitiAgenda extends Agenda{
void planOperation(Runnable operation, String param);
}
- DefaultActivitiAgenda
public class DefaultActivitiAgenda implements ActivitiAgenda{
protected LinkedList<Runnable> operations = new LinkedList<Runnable>();
public boolean isEmpty() {
return operations.isEmpty();
}
public Runnable getNextOperation() {
return operations.poll();
}
public void planOperation(Runnable operation) {
planOperation(operation, null);
}
public void planOperation(Runnable operation, String param) {
operations.add(operation);
}
}
4、CommandExecutor
- CommandExecutor
public interface CommandExecutor {
<T> T execute(CommandConfig config, Command<T> command);
<T> T execute(Command<T> command);
}
- CommandExecutorImpl
public class CommandExecutorImpl implements CommandExecutor{
protected CommandConfig defaultConfig;
protected CommandInterceptor first;
public CommandExecutorImpl(CommandConfig defaultConfig,
CommandInterceptor first) {
super();
this.defaultConfig = defaultConfig;
this.first = first;
}
public CommandInterceptor getFirst() {
return first;
}
public void setFirst(CommandInterceptor first) {
this.first = first;
}
public CommandConfig getDefaultConfig() {
return defaultConfig;
}
public void setDefaultConfig(CommandConfig defaultConfig) {
this.defaultConfig = defaultConfig;
}
public <T> T execute(Command<T> command) {
return first.execute(defaultConfig, command);
}
public <T> T execute(CommandConfig config, Command<T> command) {
return first.execute(config, command);
}
}
5、CommandContextCloseListener
public interface CommandContextCloseListener {
void closing(CommandContext commandContext);
void closed(CommandContext commandContext);
}
6、CommandContext
public class CommandContext {
protected Command<?> command;
protected ActivitiAgenda agenda;
protected Throwable exception;
protected List<CommandContextCloseListener> closeListeners;
protected boolean reused;
protected Object result;
public CommandContext(Command<?> command, EngineConfiguration engineConfiguration) {
this.command = command;
this.agenda = engineConfiguration.createAgenda();
}
public void addCloseListener(CommandContextCloseListener closeListener){
if(closeListeners == null){
closeListeners = new ArrayList<CommandContextCloseListener>();
}
closeListeners.add(closeListener);
}
public void close(){
try{
executeCloseListenersClosing();
if(exception != null){
//TODO
System.out.println("flushSessions...");
}
}catch(Exception e){
exception(e);
}finally{
//TODO
executeCloseListenersClosed();
}
}
protected void executeCloseListenersClosing() {
if(closeListeners != null){
try{
for(CommandContextCloseListener listener : closeListeners){
listener.closing(this);
}
}catch(Throwable exception){
exception(exception);
}
}
}
protected void executeCloseListenersClosed() {
if(closeListeners != null){
try{
for(CommandContextCloseListener listener : closeListeners){
listener.closed(this);
}
}catch(Throwable exception){
exception(exception);
}
}
}
public void exception(Throwable exception){
if(this.exception == null){
this.exception = exception;
}else{
exception.printStackTrace();
}
}
public Command<?> getCommand() {
return command;
}
public ActivitiAgenda getAgenda() {
return agenda;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
public boolean isReused() {
return reused;
}
public void setReused(boolean reused) {
this.reused = reused;
}
}
7、CommandConfig
public class CommandConfig {
private boolean reuse;
public CommandConfig() {
this.reuse = true;
}
public boolean isReuse() {
return reuse;
}
public void setReuse(boolean reuse) {
this.reuse = reuse;
}
}
8、Context
public class Context {
protected static ThreadLocal<Stack<CommandContext>> commandContextLocal = new ThreadLocal<Stack<CommandContext>>();
protected static ThreadLocal<Stack<EngineConfiguration>> engineConfigurationLocal = new ThreadLocal<Stack<EngineConfiguration>>();
public static CommandContext getCommandContext(){
Stack<CommandContext> stack = getStack(commandContextLocal);
if(stack.isEmpty()){
return null;
}
return stack.peek();
}
public static EngineConfiguration getProcessEngineConfiguration(){
Stack<EngineConfiguration> stack = getStack(engineConfigurationLocal);
if(stack.isEmpty()){
return null;
}
return stack.peek();
}
public static void setCommandContext(CommandContext commandContext){
getStack(commandContextLocal).push(commandContext);
}
public static void removeCommandContext(){
getStack(commandContextLocal).pop();
}
public static void setEngineConfiguration(EngineConfiguration engineConfiguration){
getStack(engineConfigurationLocal).push(engineConfiguration);
}
public static void removeEngineConfiguration(){
getStack(engineConfigurationLocal).pop();
}
protected static <T> Stack<T> getStack(ThreadLocal<Stack<T>> threadLocal){
Stack<T> stack = threadLocal.get();
if(stack == null){
stack = new Stack<T>();
threadLocal.set(stack);
}
return stack;
}
}
9、CommandContextFactory
public class CommandContextFactory {
protected EngineConfiguration engineConfiguration;
public CommandContext createCommandContext(Command<?> command){
return new CommandContext(command, engineConfiguration);
}
public EngineConfiguration getEngineConfiguration() {
return engineConfiguration;
}
public void setEngineConfiguration(EngineConfiguration engineConfiguration) {
this.engineConfiguration = engineConfiguration;
}
}
10、EngineConfiguration
public class EngineConfiguration {
protected CommandConfig defaultCommandConfig;
protected CommandExecutor commandExecutor;
protected List<CommandInterceptor> commandInterceptors;
protected CommandInterceptor commandInvoker;
protected CommandContextFactory commandContextFactory;
public EngineConfiguration() {
init();
}
public void init(){
initCommandContextFactory();
initCommandConfig();
initCommandInvoker();
initCommandInterceptors();
initCommandExecutor();
}
private void initCommandInvoker() {
if(commandInvoker == null){
commandInvoker = new CommandInvoker();
}
}
private void initCommandConfig() {
if(defaultCommandConfig == null){
defaultCommandConfig = new CommandConfig();
}
}
private void initCommandInterceptors() {
if(commandInterceptors == null){
commandInterceptors = new ArrayList<CommandInterceptor>();
commandInterceptors.addAll(getDefaultCommandInterceptors());
commandInterceptors.add(commandInvoker);
}
}
private void initCommandExecutor() {
if(commandExecutor == null){
CommandInterceptor first = initInterceptorChain(commandInterceptors);
commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
}
}
private void initCommandContextFactory() {
if(commandContextFactory == null){
commandContextFactory = new CommandContextFactory();
}
commandContextFactory.setEngineConfiguration(this);
}
private CommandInterceptor initInterceptorChain(List<CommandInterceptor> chain) {
if(chain == null || chain.isEmpty()){
throw new RuntimeException("invalid command interceptor chain: " + chain);
}
for(int i = 0; i < chain.size() - 1; i++){
chain.get(i).setNext(chain.get(i + 1));
}
return chain.get(0);
}
public List<CommandInterceptor> getDefaultCommandInterceptors(){
List<CommandInterceptor> interceptors = new ArrayList<CommandInterceptor>();
interceptors.add(new LogInterceptor());
interceptors.add(new CommandContextInterceptor(commandContextFactory, this));
return interceptors;
}
public ActivitiAgenda createAgenda(){
return new DefaultActivitiAgenda();
}
public CommandConfig getDefaultCommandConfig() {
return defaultCommandConfig;
}
public void setDefaultCommandConfig(CommandConfig defaultCommandConfig) {
this.defaultCommandConfig = defaultCommandConfig;
}
public CommandExecutor getCommandExecutor() {
return commandExecutor;
}
public void setCommandExecutor(CommandExecutor commandExecutor) {
this.commandExecutor = commandExecutor;
}
}
二、执行Cmd
public class App
{
public static void main( String[] args )
{
EngineConfiguration engineConfiguration = new EngineConfiguration();
engineConfiguration.getCommandExecutor().execute(new DoSomethingCmd());
}
}
输出:
start...
do something...
finish...