Activiti UEL 表达式
UEL表达式到底是什么呢?
UEL是java EE6规范的一部分,UEL(Unified Expression Language)即统一表达式语言,activiti支持两个UEL表达式:UEL-value和UEL-method
Activiti使用UEL进行表达式解析(有关详细信息,请参阅EE6规范)
Activiti 如何使用UEL表达式获取Spring 容器中的bean?
答案在activiti-spring.jar中
SpringExpressionManager.java //spring表达式管理类
public class SpringExpressionManager extends ExpressionManager {
//应用上下文
protected ApplicationContext applicationContext;
public SpringExpressionManager(ApplicationContext applicationContext, Map<Object, Object> beans) {
super(beans);//这个beans是流程引擎中的beans
this.applicationContext = applicationContext;
}
@Override
protected ELResolver createElResolver(VariableScope variableScope) {
//复合el表达式
CompositeELResolver compositeElResolver = new CompositeELResolver();
compositeElResolver.add(new VariableScopeElResolver(variableScope));
//判断beans是否为空
if (beans != null) {
// 在表达式中只暴露流程引擎中的beans
compositeElResolver.add(new ReadOnlyMapELResolver(beans));
} else {
// 在表达式中暴露整个application-context
compositeElResolver.add(new ApplicationContextElResolver(applicationContext));
}
//添加数组解析器
compositeElResolver.add(new ArrayELResolver());
//添加集合解析器
compositeElResolver.add(new ListELResolver());
//添加map解析器
compositeElResolver.add(new MapELResolver());
//添加json格式的数据解析器 like {key:value,...} or [1,2,3,4,...]
compositeElResolver.add(new JsonNodeELResolver());
//添加bean解析器
compositeElResolver.add(new BeanELResolver());
return compositeElResolver;
}
在ProcessEngineConfigurationImpl.java中调用
public class ProcessEngineFactoryBean implements FactoryBean<ProcessEngine>, DisposableBean, ApplicationContextAware {
...
protected void configureExpressionManager() {
if (processEngineConfiguration.getExpressionManager() == null && applicationContext != null) {
processEngineConfiguration.setExpressionManager(new SpringExpressionManager(applicationContext, processEngineConfiguration.getBeans()));
}
}
...
}
使用表达式
Activiti的Expression 接口
public interface Expression extends Serializable {
// variableScope 为变量作用域
Object getValue(VariableScope variableScope);
void setValue(Object value, VariableScope variableScope);
String getExpressionText();
}
在代码中的具体使用
//获取表达式对象
//execution 为 VariableScope 的实现类 用于从不同的变量作用域中取变量
Expression expression = expressionManager.createExpression("${bean.id}");
businessKey = expression.getValue(execution).toString();
为什么有VariableScope
因为Activiti中有很多流程,每一个流程都有很多变量,使用变量的时候肯定不能去拿其他流程的变量,为了更好的管理在表达式中使用变量,所以这里就有了一个变量作用域的概念
通过变量作用域获得EL上下文
public class ExpressionManager {
...
public ELContext getElContext(VariableScope variableScope) {
ELContext elContext = null;
if (variableScope instanceof VariableScopeImpl) {
VariableScopeImpl variableScopeImpl = (VariableScopeImpl) variableScope;
elContext = variableScopeImpl.getCachedElContext();
}
if (elContext == null) {
//如果没有就创建一个EL上下文
elContext = createElContext(variableScope);
if (variableScope instanceof VariableScopeImpl) {
((VariableScopeImpl) variableScope).setCachedElContext(elContext);
}
}
return elContext;
}
...
}
VariableScope 的实现类
实现类就只要有三个类
- NoExecutionVariableScope.java
- TaskEntityImpl.java
- ExecutionEntityImpl.java
其中VariableScopeImpl 是个抽象类,这里使用了模板模式
需要子类实现的方法
protected abstract Collection<VariableInstanceEntity> loadVariableInstances();
protected abstract VariableScopeImpl getParentVariableScope();
protected abstract void initializeVariableInstanceBackPointer(VariableInstanceEntity variableInstance);
protected abstract VariableInstanceEntity getSpecificVariable(String variableName);
JUEL实现类
public class JuelExpression implements Expression {
protected String expressionText;
protected ValueExpression valueExpression;
public JuelExpression(ValueExpression valueExpression, String expressionText) {
this.valueExpression = valueExpression;
this.expressionText = expressionText;
}
public Object getValue(VariableScope variableScope) {
//获取值的时候都要通过variableScope获取上下文
ELContext elContext = Context.getProcessEngineConfiguration().getExpressionManager().getElContext(variableScope);
try {
ExpressionGetInvocation invocation = new ExpressionGetInvocation(valueExpression, elContext);
Context.getProcessEngineConfiguration().getDelegateInterceptor().handleInvocation(invocation);
return invocation.getInvocationResult();
} catch (PropertyNotFoundException pnfe) {
throw new ActivitiException("Unknown property used in expression: " + expressionText, pnfe);
} catch (MethodNotFoundException mnfe) {
throw new ActivitiException("Unknown method used in expression: " + expressionText, mnfe);
} catch (ELException ele) {
throw new ActivitiException("Error while evaluating expression: " + expressionText, ele);
} catch (Exception e) {
throw new ActivitiException("Error while evaluating expression: " + expressionText, e);
}
}
public void setValue(Object value, VariableScope variableScope) {
ELContext elContext = Context.getProcessEngineConfiguration().getExpressionManager().getElContext(variableScope);
try {
ExpressionSetInvocation invocation = new ExpressionSetInvocation(valueExpression, elContext, value);
Context.getProcessEngineConfiguration().getDelegateInterceptor().handleInvocation(invocation);
} catch (Exception e) {
throw new ActivitiException("Error while evaluating expression: " + expressionText, e);
}
}
@Override
public String toString() {
if (valueExpression != null) {
return valueExpression.getExpressionString();
}
return super.toString();
}
public String getExpressionText() {
return expressionText;
}
}