在非微服务的项目中,一个应用里有多个子系统,例如在一个电商系中,有系统管理子系统、内容管理子系统和电商管理子系统,我们想实现这样的效果:
(1)只需要启动一个SpringBoot应用,不需要每个子系统都单独启动一个应用。
(2)只需要配置一个application.yml或application-dev.yml,不需要在每个子系统单独配置yml。
(3) 启动一个SpringBoot应用,各个子系统的@RestController和@Controller接口都可以访问,
而且是基于一个端口。
(4)其他子系统都可以跨模块调用系统管理子系统的服务。例如电商子系统可以调用系统管理子
系统里的用户Service和部门Service。
这样我们需要对主工程、核心工程、starter工程、系统管理模块、其他各子系统模块的依赖关系进行梳理,并根据梳理的依赖关系修改工程里的模块依赖。
在上图中,openjweb-common是基础工程,含通用的底层通用类库。openjweb-starter为各种启动工程。openjweb-core是核心工程(系统管理相关的如组织机构、权限、角色、用户管理、数据字典等,为各业务子系统都依赖的公共API和服务),openjweb-b2c、openjweb-cms代表各业务系统如电商、内容管理系统。openjweb-sys依赖各业务系统,这样启动时,启动在openjweb-sys的SpringBoot应用,application.yml或application-dev.yml项目配置参数只需要配置在openjweb-sys工程中,这样免得到各个模块中单独配置。
按照上面的规划,总工程的pom.xml包含所有子模块:
openjweb-common是底层类库,不依赖其他模块。不过注意不要在pom.xml里加build和springboot-starter。但需要根据情况增加web相关依赖(如果openjweb-common不开发Controller的话,则不需要加Web相关的依赖):
<dependencies><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId></dependency></dependencies>
openjweb-core中增加对openjweb-common的依赖,另外因为openjweb-core中会有@RestController、@Controller、@Service,所以需要添加Web相关的依赖,下面是openjweb-core的pom.xml的依赖:
<dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.openjweb</groupId><artifactId>openjweb-common</artifactId><version>0.0.1-SNAPSHOT</version><scope>compile</scope></dependency></dependencies>
openjweb-sys是启动应用的包,所以依赖openjweb-core和所有的子系统,因为需要通过localhost:8001/ 访问到所有子系统里的接口:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.openjweb</groupId><artifactId>datasource-openjweb-starter</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.openjweb</groupId><artifactId>redis-openjweb-starter</artifactId><version>0.0.1-SNAPSHOT</version><scope>compile</scope></dependency><dependency><groupId>org.openjweb</groupId><artifactId>openjweb-core</artifactId><version>0.0.1-SNAPSHOT</version><scope>compile</scope></dependency><dependency><groupId>org.openjweb</groupId><artifactId>openjweb-sns</artifactId><version>0.0.1-SNAPSHOT</version><scope>compile</scope></dependency><dependency><groupId>org.openjweb</groupId><artifactId>openjweb-cms</artifactId><version>0.0.1-SNAPSHOT</version><scope>compile</scope></dependency><dependency><groupId>org.openjweb</groupId><artifactId>openjweb-b2c</artifactId><version>0.0.1-SNAPSHOT</version><scope>compile</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
注意依赖的子系统需要增加<scope>compile</scope>。
现在我们做几个示例,首先是在openjweb-sys启动时,可以访问openjweb-core 里的查询公司信息接口:
在openjweb-core的org.openjweb.core.api下面创建一个CommCompanyApi.java:
package org.openjweb.core.api;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RequestMapping("/api/comm/company")
@RestController
public class CommCommpanyApi {//localhost:8001/api/comm/company/query@RequestMapping("query")public String getComName(){String comName = "百度";return comName;}
}
然后启动openjweb-sys,访问http://localhost:8001/api/comm/company/query ,页面显示:
说明openjweb-sys可以访问其他模块的接口。
接下来我们看下在openjweb-core中能否使用以前课程定义的数据库组件访问数据库,还在这个CommCompanyApi增加下面的代码:
@Resource(name = "jdbcTemplateOne")private JdbcTemplate service;//localhost:8001/api/comm/company/queryDb@RequestMapping("queryDb")public String getComNameDb(){int count = service.queryForObject("select count(*) from comm_system_parms ",Integer.class);return String.valueOf(count);}
前面章节示例中创建了comm_system_parms并插入了记录,启动openjweb-sys的SpringBoot应用,访问http://localhost:8001/api/comm/company/queryDb :
可以成功查询数据库。
另外我们再测试下能否在其他子系统里访问openjweb-core里的Service。如果可以的话,我们就可以在其他系统里调用openjweb-core里的用户、部门、人员等基础Service。我们首先在openjweb-core工程的org.openjweb.core.service下面创建一个CommDeptService.java (部门Service):
package org.openjweb.core.service;import org.springframework.stereotype.Service;@Service
public class CommDeptService {public String getDeptDemoName(String comId){return "研发部";}}
这里补充说明一下,之前建的 openjweb-b2c子模块有问题,就是不管怎样也没法调用openjweb-b2c的接口,所以删掉了openjweb-b2c模块,重新增加了openjweb-b2b2c模块,上面所有关于openjweb-b2c模块的命名都改为openjweb-b2c。
然后我们看下openjweb-b2b2c模块的依赖:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.openjweb</groupId><artifactId>openjweb-core</artifactId><version>0.0.1-SNAPSHOT</version><scope>compile</scope></dependency></dependencies>
注意上面的
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
这段不要手工加,手工加的好像系统不认,而是下面写API时引用@RestController时这行标红,用Alt+Enter会导入库依赖并自动在pom.xml里添加,如果已经添加了会重复添加。下面我们看下增加的测试类B2cDeptApi.java :
package org.openjweb.b2c.api;import org.openjweb.core.service.CommDeptService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;@RequestMapping("/api/b2b2c/dept")
@RestController
public class B2cDeptApi {//localhost:8001/api/b2b2c/dept/query@RequestMapping("query")public String getDeptName(){String name = "研发部1";return name;}@Resourceprivate CommDeptService commDeptService;//localhost:8001/api/b2b2c/dept/queryService@RequestMapping("queryService")public String getDeptName2(){String name = commDeptService.getDeptDemoName("");return name;}
}
getDeptName演示了调用openjweb-b2b2c包里的api接口,启动openjweb-sys的springboot应用后,访问 http://localhost:8001/api/b2b2c/dept/query :
第二个方法deptDeptName2演示了调用openjweb-core里的CommDeptService服务组件,通过
@Resource 引用了这个组件,这说明可以调用不同模块的业务组件。访问http://localhost:8001/api/b2b2c/dept/queryService ,显示下面的页面:
调用成功。大家搭建新项目时需要测试下模块的依赖,否则会影响后面项目代码的结构设计。
项目代码可从Github下载:GitHub - openjweb/cloud at masterOpenJWeb is a java bases low code platform. Contribute to openjweb/cloud development by creating an account on GitHub.https://github.com/openjweb/cloud/tree/master