众所周知在spring中工作流引擎activiti/flowable是可以通过委托表达式获取到spring bean的。但在micronaut中会报这个异常,因为activiti/flowable官方已经集成好了spring,而micronaut并没有人帮你集成过,获取不到容器里的bean是理所当然的。
由于micronaut是个新框架,网上翻了一圈都没找到对路的文章,以及在micronaut中怎么解决。
无奈之下自能自己出手了,翻了翻flowable的源码,找到跟spring集成部分的代码,理解了一下,模仿着写了一个针对micronaut的简单集成,打通flowable和micronaut容器,经过一番调试之后问题解决。
在给任务节点设置监听器,运行到这个节点时会出现这个异常flowable Unknown property used in expression: ${testListener}
,监听器的设置如下图所示,设置了委托表达式delegateExpression,本意是想获取一个bean作为监听器。
对应的xml为:
<userTask id="task1" name="task1" flowable:formFieldValidation="true">
<extensionElements>
<flowable:taskListener event="complete" delegateExpression="${billGenerateListener}">
</flowable:taskListener>
</extensionElements>
</userTask>
监听器代码如下:
@Context
@Named("billGenerateListener")//监听器名称,跟委托表达式里的设置对应
public class BillGenerateTaskListener implements TaskListener {
@Override
public void notify(final DelegateTask delegateTask) {
delegateTask.getTaskDefinitionKey();
final Map<String, Object> variables = delegateTask.getVariables();
final Object costPrice = variables.get("costPrice");
log.warn("Generate Bill...");
log.warn("costPrice:{}",costPrice);
}
}
下面直接看怎么解决的吧,不扯什么工作原理、底层机制,我们只是为了解决问题,直接抄了能用最好!
我们知道flowable引擎对象ProcessEngine
一般是通过ProcessEngineConfiguration#buildProcessEngine()
创建的,这是使用引擎的入口。
那么需要在ProcessEngineConfiguration
中设置一个自己扩展的ProcessExpressionManager
cfg.setExpressionManager(
new MicronautExpressionManager(applicationContext, cfg.getBeans()));
MicronautExpressionManager:
public class MicronautExpressionManager extends ProcessExpressionManager {
protected ApplicationContext applicationContext;//micronaut的context
public MicronautExpressionManager(ApplicationContext applicationContext, Map<Object, Object> beans) {
super(beans);
this.applicationContext = applicationContext;
}
@Override
protected ELResolver createElResolver(VariableContainer variableContainer) {
CompositeELResolver compositeElResolver = new CompositeELResolver();
compositeElResolver.add(createVariableElResolver(variableContainer));
compositeElResolver.add(createMicronautElResolver());//主要是这里
compositeElResolver.add(new ArrayELResolver());
compositeElResolver.add(new ListELResolver());
compositeElResolver.add(new MapELResolver());
compositeElResolver.add(new JsonNodeELResolver());
compositeElResolver.add(new BeanELResolver());
compositeElResolver.add(new CouldNotResolvePropertyELResolver());
return compositeElResolver;
}
protected ELResolver createMicronautElResolver() {
if (beans != null) {
return new ReadOnlyMapELResolver(beans);
} else {
// 还有这里,在表达式中暴露 application-context
return new MicronautApplicationContextElResolver(applicationContext);
}
}
}
再看下MicronautApplicationContextElResolver:
public class MicronautApplicationContextElResolver extends ELResolver {
protected ApplicationContext applicationContext;
public MicronautApplicationContextElResolver(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
//主要就是这里通过bean名称获取micronaut的bean
@Override
public Object getValue(ELContext context, Object base, Object property) {
if (base == null) {
String key = (String) property;
final Object o = applicationContext.getBean( Object.class, Qualifiers.byName(key));
if (o!=null) {
context.setPropertyResolved(true);
return o;
}
}
return null;
}
@Override
public boolean isReadOnly(ELContext context, Object base, Object property) {
return true;
}
@Override
public void setValue(ELContext context, Object base, Object property, Object value) {
if (base == null) {
String key = (String) property;
final Object o = applicationContext.getBean( Object.class, Qualifiers.byName(key));
if (o!=null) {
throw new FlowableException("Cannot set value of '" + property + "', it resolves to a bean defined in the micronaut application-context.");
}
}
}
@Override
public Class<?> getCommonPropertyType(ELContext context, Object arg) {
return Object.class;
}
@Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object arg) {
return null;
}
@Override
public Class<?> getType(ELContext context, Object arg1, Object arg2) {
return Object.class;
}
}
好了,抄完作业就阔以了。
原文发表于http://jenwang.me
更多交流请关注公众号:
家里买了台 NETGEAR 路由器刷了梅林固件,可以在 USB 接口上挂个存储当 NAS 用,发现家里的移动宽带是没有公网 ip 的,于是在外网访问不到内网,ddns 也没法用了(不要给我推荐花生壳内网版😝)。那么,需求就是如何让外网访问到内网ip。
于是想到了从内网到公网上的某台机器建立一条 ssh 隧道,通过访问公网机器把数据穿透到内网,实现方法:
在内网 10.96.x.x 上执行 ssh -N -f -R 8088:10.96.x.x:443 root@167.88.x.x -b 0.0.0.0 "vmstat 30"
让外网可以通过公网的 167.88.x.x:8088 访问到内网10.96.x.x:443
备注:167.88.x.x上需要在
/etc/sshd/sshd_config
中修改GatewayPorts no
为GatewayPorts yes
,
否则 8088 端口是绑定在 127.0.0.1 上的,只有本机能访问。
群晖的 quickconnect,以及内网版的 ddns 原理应该都类似,实现方式可能有所不同。这种可用性关键在于公网中转服务器的网速和通道的稳定性。
观察到许多公司常见的一种现象,出现了某些瓶颈,希望招个水平高的来突破。然而瓶颈往往是由于自身在某方面或全局的认知水平决定的,新招进来的人往往只能在原有的认知模式下工作,结果经常是这样的:要么融入其中但没啥作为,要么受不了而离开。
一路磕磕绊绊,遇到不少问题,也有一点微小的心得,这次就写记录管理方面的。
做为管理者不能逻辑混乱,前后逻辑要一致,「自洽」都做不到是很糟糕的,员工会一头雾水甚至抱怨。每次一遇到问题就想制定相应的措施,但后续的问题往往恰好相反,如果因某些小概率错误就大动干戈制定措施,只会给公司带来伤疤。
例如,
继续阅读 →这个坑是去年挖的,后来想填发现内容想不起来了,今天想起来了就简略填一下吧。
经常听说90后的个性更加自我,崇尚自由,叛逆,不服从权威等,然后得出针对90后的管理方法应该转变,认为他们不像70、80后那样服从管理和隐忍,在做自己想做的事才能发挥最大的积极性,用僵硬的规则管理会让他们觉得缺乏自由而产生负面效果,应该以激发成就感和认同感为主,从而带动工作效率。
认同这种想法的人已经是善于接受新事物的了,没得出负面结论已经不错了。但是,有一点我并不认同…
继续阅读 →本书主要讲了新时代科技企业的特点以及传统家长制、规划和控制等管理方式的弊端,提出了一种新的管理范式「合弄制」(这个翻译感觉怪怪的)。「合弄制」主要思想是分权自治,抛弃传统的层级管理结构采用圈子的形式作为组织结构,个人和圈子都具备自治权,同时伴随着责任,遵循章程办事,从人治到法治,既解放管理者又把权力交还给工作过程,发挥每个人的主动性和价值。
有人说这是「敏捷开发」的企业版,确实有异曲同工之处。与敏捷开发类似,认为一切都是在变化之中的,因而更倾向于根据实际反馈动态调整工作,而非以初始规划为重,然后提出一套实际操作手法,例如,章程制定、会议形式、人员组织形式等。
倘若完全照搬未免落入死板被动的境地,具体方法都套用的话也就落入了「重量级」的俗套,许多做法听起来是这么回事,但实际工作环境和团队情况千差万别,指某种使用「银弹」般的管理方法而后就可以安枕无忧的想法不现实。至于书本中提倡整个企业采取颠覆式的变动来推行,未免过于乐观,就像作者说的不愿放权的领导
,不愿合作的中层
,突然停止综合症
等阻碍,还只是冰山一角,不具体展开。确实有非常好的理念,这种做事氛围也是自己认同和向往的,但也有鼓吹的成分,有些内容信服度不高。书中的一个重要观点是根据实际反馈动态调整
,那么扩展一下可以同样用于「合弄制」本身,通过吸收令人反思的部分来改善管理工作,获得更加适合于自己的方式。
作者: [日] 坂井丰贵
开始看到这本书其实挺惊讶的,有种见微知著的感觉,看上去如此平常简单的事情,竟然可以通过理论体系和算法得到更合理的解决,而不是凭感觉行事。那么日常中,我们一直采用无知落后的方式来做决策而不自知的有多少?
深感市场设计的魅力,以及为经济学家思维的层次感与创造力所折服
。制度和游戏规则设计绝不是件简单的事,有时甚至需要经过理论和公式的严密论证。良好的规则应该获得优化结果的同时还能防止策略性操作,使得表达真实意图和诚信的行为得到鼓励,消除碰运气和投机性而获利的可能。
以下记录本书的关键点,本书分三个部分,
继续阅读 →作者: [日] 冈仓天心
感想与摘录
原以为是介绍喝茶知识的书,然而并不是。一直对日本诸多侘寂之美的设计颇为赞赏,简朴亲切而又实用摒弃任何多余的干扰,然而对于这种审美的根基一无所知,看完后又刷新了对日本的一些认知,对简约朴素的审美和文化之渊源有了全新的了解,甚是惊喜。
译者的后记是本书不可忽视的篇章,更通透地解释了中日文化渊源和差异,视角非常有启发。中国艺术的背后主要是权力、审美的统治,而日本则是普通民众的力量,民艺运动通过改善民众的生活品质进而促进社会进步。日本茶道的建立是对这种审美统治的挑战,属于自己空间关系的审美而非复制中国的审美,我们总是提传统文化的保护却很少钻研传统文化的发展,传统不应该成为包袱,应该随时蜕去积攒千年的壳,关照事物纯粹的本质,没有创造无所谓传统,传统是创造的积淀。极为认同译者所言中国没有茶道,中国有饮茶的方法
,近年来大陆的饮茶之风日盛,只是附庸风雅、软弱无力,是虚假和令人生厌的,没有文化的优雅是妖,再多的人声鼎沸也只能是繁华躁动且妖气弥漫。