基于超图SuperMap iObjects JAVA的SpringBoot工程搭建与整合(三)—— SuperMap iObjects JAVA如何与Spring的IOC结合
第一章:Nexus搭建与Maven引入
第二章:SuperMap iObjects JAVA 在SpringBoot工程中如何进行参数化配置
第三章:SuperMap iObjects JAVA如何与Spring的IOC结合
第四章:SuperMap iObjects JAVA作为Web后台的二开,在MVC中扮演什么角色,如何优雅的组织代码?
第五章:聊一聊SuperMap iObjects JAVA的奇葩设计,阅读避坑(持续更新~)
文章目录
为什么要啰嗦这个?
期初接触SuperMap iObject JAVA的时候,总感觉这玩意不适合做Web Service。无论从帮助文档的说明上,还是从父类子类的结构上,还是从静态方法的设计上,处处携带着C/S架构设计的风格。当然只是个人感官,勿喷····
使用Spring IOC、AOP的主要目的是为了实现模块之间的解耦合。那么该怎么让GIS核心代码解耦呢?
IOC是什么?
IOC(控制反转)就是依赖倒置原则的一种代码设计思路。就是把原先在代码里面需要实现的对象创建、对象之间的依赖,反转给容器来帮忙实现。
Spring IOC容器通过xml,注解等其它方式配置类及类之间的依赖关系,完成了对象的创建和依赖的管理注入。实现IOC的主要设计模式是工厂模式。
IOC的原理
在编码阶段,既没有实例化对象,也没有设置依赖关系,而把它交给Spring,由Spring在运行阶段实例化、组装对象。这种做法颠覆了传统的写代码实例化、组装对象、然后一步步执行的做法,因此被称为反向控制(Inverse of Control),或者反转控制。
说了这么多,总结一下:使用Spring框架整合其他任何第三方工具,最优雅的方式就是将实例化工作交给Spring完成。
SuperMap iObjects JAVA是否适用IOC?
我考虑过两种方式将SuperMap iObjects JAVA整合到SpringBoot工程中。
第一种:将工作空间的初始化代码使用单例模式完成,这样工程中有且仅有一个链接类的实例,符合使用层面的要求。但是单例模式只能保证单一链接。对于逻辑代码的使用还是需要频繁获取这个实例。
第二种,将工作空间的初始化代码交给IOC,在逻辑代码中 @Autowired注入。这样就完美解决了频繁获取实例额问题,而且SuperMap iObjects JAVA工作空间的打开也是允许多个端同时访问的,问题不大。
一、从工作空间说起
初始化工作空间:
package com.supermap.service;
import com.supermap.config.YoungSuperMapConfig;
import com.supermap.data.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 工作空间链接管理与数据源管理
*/
@Component
public class WorkSpaceService {
@Autowired
private YoungSuperMapConfig config;
private Workspace workspace;
private Datasources datasources;
private Maps maps;
/**
* 初始化工作空间和数据源
*/
private void init() {
workspace = new Workspace();
WorkspaceConnectionInfo workspaceConnectionInfo = new WorkspaceConnectionInfo();
// 兼容pg工作空间
workspaceConnectionInfo.setType(config.getDatabase() == null ? WorkspaceType.SMWU : WorkspaceType.PGSQL);
workspaceConnectionInfo.setVersion(WorkspaceVersion.UGC70);
workspaceConnectionInfo.setServer(config.getServer());
workspaceConnectionInfo.setDatabase(config.getDatabase());
workspaceConnectionInfo.setUser(config.getUser_database());
workspaceConnectionInfo.setPassword(config.getPassword_database());
workspaceConnectionInfo.setName(config.getName_database());
// 打开工作空间
workspace.open(workspaceConnectionInfo);
datasources = workspace.getDatasources();
}
/**
* 检查工作空间
*/
private synchronized void checkWorkspace() {
if (workspace == null) {
init();
}
}
/**
* 获取工作空间
*
* @return
*/
public synchronized Workspace getWorkspace() {
checkWorkspace();
return workspace;
}
}
二、管理数据源、数据集、地图、场景等
代码如下(示例):
package com.supermap.service;
import com.supermap.config.YoungSuperMapConfig;
import com.supermap.data.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 工作空间链接管理与数据源管理
*/
@Component
public class WorkSpaceService {
@Autowired
private YoungSuperMapConfig config;
private Workspace workspace;
private Datasources datasources;
private Maps maps;
/**
* 检查数据源
*/
private synchronized void checkDatasources() {
if (datasources == null) {
init();
}
}
/**
* 检查地图
*/
private synchronized void checkMaps() {
if (maps == null) {
init();
}
}
/**
* 关闭数据源
*
* @param name
*/
public synchronized void closeDatasource(String name) {
checkDatasources();
datasources.close(name);
}
/**
* 获取数据源
*
* @return
*/
public synchronized Datasource getDatasource(String name) {
checkDatasources();
Datasource datasource = datasources.get(name);
return datasource;
}
/**
* 获取地图集合
*
* @return
*/
public synchronized Maps getMaps() {
checkMaps();
return maps;
}
}
三、以一个GeometryService、GeometryServiceImpl为例
GeometryService.java
/**
* cad解析导出
*/
public interface GeometryService {
public String parsingCAD(String sourceFile, String projectId) throws Exception;
//制作地图
public void makeMap(String projectId);
//生成cad
public String makeCAD(String projectId);
}
GeometryServiceImpl.java
/**
* cad解析导出
*/
@Service
public class GeometryServiceImpl implements GeometryService {
@Autowired
private WorkSpaceUtils workSpaceUtils;
@Autowired
private ISysConfigService configService;
/**
* 解析CAD
* @param sourceFile
* @param projectId
* @return
* @throws Exception
*/
@Override
public String parsingCAD(String sourceFile, String projectId) throws Exception {
Datasource temp = workSpaceUtils.getDatasource(configService.selectConfigByKey("supermap.temp_datasource"));
Datasource young = workSpaceUtils.getDatasource(configService.selectConfigByKey("supermap.datasource"));
// 清空temp里面所有的数据集,防止上次的导入失败之后,里面遗留的是之前的老数据
DataSourceUtils.delAllDataset(temp);
DataSourceUtils.importCAD(sourceFile, temp);
// 获取2000坐标系
//中间逻辑代码简略
// 清空temp里面所有的数据集
DataSourceUtils.delAllDataset(temp);
return "";
}
/**
* 生成地图
* @param projectId
*/
@Override
public void makeMap(String projectId) {
Datasource young = workSpaceUtils.getDatasource(configService.selectConfigByKey("supermap.datasource"));
Workspace workspace = workSpaceUtils.getWorkspace();
Map<String, String> templeteMap = getTempleteMap();
//中间逻辑代码简略
}
}
四、geometryService在Controller的使用
@RestController
@RequestMapping("/traffic/project")
public class TrafficProjectController extends BaseController {
@Autowired
private GeometryService geometryService;
@PreAuthorize("@ss.hasPermi('traffic:project:export')")
@GetMapping("/exportCAD")
public AjaxResult exportCAD(TrafficProject trafficProject) {
String protectCad = geometryService.makeCAD(trafficProject.getProjectId().toString());
boolean result = geometryService.exportCAD(protectCad);
String url = RESOURCE_PREFIX + YoungConfig.getDownloadAbsolutePath() + protectCad + ".dwg";
return result == true ? AjaxResult.success("生成成功", url) : AjaxResult.error("生成失败");
}
@GetMapping("/checkRegion")
public AjaxResult checkRegion(@RequestParam String dataSetName) {
Map result = geometryService.checkRegion(dataSetName);
return AjaxResult.success("检查区域边界",result);
}
总结
这个系列文章所涉及的源代码,会放到资源库中供大家下载
欢迎GIS开发的小伙伴留言交流!
下一章:SuperMap iObjects JAVA作为Web后台的二开,在MVC中扮演什么角色,如何优雅的组织代码