问题:
楼主最近做了一个规则比较多的项目,甲方爸爸非得让用drools这个开源框架.所以楼主就在网上搜索了一个demo.然后照demo将项目给敲完了.但是到最后打包上测试的时候发现一个严重的问题,就是spring boot项目在package后.然后部署上测试运行包资源路径下的文件加载不到的问题..
demo地址:Sample-Drools: 规则引擎Drools示例
思考:
因为考虑到drools的性能,决定将资源路径下的规则文件配置在spring bean容器中,当时采用的是资源路径加载的方式.代码如下:
/**
*获取资源路径下的文件
*/
private Resource[] getRuleFiles() throws IOException {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resourcePatternResolver.getResources( RULES_PATH +"*.*");
return resources;
}
RULES_PATH 表示资源文件下的文件夹名;
然后将加载资源的文件配置在KnowledgeBuilder的容器中,是直接进行加载的 代码:
@Bean
public KnowledgeBuilder getKnowledgeBuilder() throws IOException{
KnowledgeBuilder builder=KnowledgeBuilderFactory.newKnowledgeBuilder();
for (Resource file : getRuleFiles() ){
builder.add(ResourceFactory.newClassPathResource(RULES_PATH+"/**/*.drl"), ResourceType.DRL);
}
return builder;
}
将资源路径下文件加载进drools专用的资源路径下.然后就是这个在本地没有问题,但是打成jar包后就出现的资源路径加载不到的问题
解决:
查询官方Api的Drools ResourceFactory 类方法的newByteArrayResource(Byte[] byte); 想到先将资源文件下的文件通过流的方式转换为字符串.然后通过上面的方法将字符串转换为字节数组.加载进drools容器中. 解决代码如下:
@Bean
public KnowledgeBuilder getKnowledgeBuilder() throws IOException{
KnowledgeBuilder builder=KnowledgeBuilderFactory.newKnowledgeBuilder();
for (Resource file : getRuleFiles() ){
logger.info("已加载资源文件名 :" +file.getFilename());
InputStream is = file.getInputStream();
StringBuffer buffer = new StringBuffer();
int by = 0;
while ((by=is.read())!=-1){
buffer.append((char)by);
}
String rulesStr = buffer.toString();
builder.add(ResourceFactory.newByteArrayResource(rulesStr.getBytes()), ResourceType.DRL);
}
return builder;
}
流加载还可以外面封装一层BufferInputStream ,因为楼主项目资源文件较少就少写了一些,后续可以再进行优化.