基于Spring Boot的工程模板(无前端) --- # 工程描述 本工程是初始集成了spring boot基础包,用户可复制该工程修改配置然后开发,初始只包含必要的依赖包如:spring-boot基础包、utils、以及其他需要的组件包(视具体情况定) 依赖包的版本管理仍使用已定义的parent工程(在ibase仓库中维护) # 模板工程结构说明 结构目录如下: * templateProj(sinfoProject) ------------模块A工程根目录 * tempInterface --------模块A接口层工程 * tempService ---------模块A实现层工程 * templateXProj ------------模块B工程根目录(实际不存在) * tempXInterface --------模块B接口层工程(实际不存在) * tempXService ---------模块B实现层工程(实际不存在) * main(sinfoMain) --------------------微服务工程根目录 * tempWeb -------------微服务工程 * tempWebClient -------针对服务间调用的封装 * sample(sinfoMessage) ----一些样例工程(在复制工程后,可以删除) * msgbusDemo ----基于消息队列的调用示例(点对点/广播消息、远程方法调用与返回、通知事件、长事务处理) ##需要调整名字的地方 > 1. 目录名、类名 > 2. pom.xml > 3. application.yml ## pom.xml * 在任何目录下的pom.xml,需要调整相应的 为实际工程所想要命名的真实内容 * 同时需要调整所引用的文件夹名为实际所想要命名的真实文件夹名 ## templateProj templateProj 是工程组织的模板,其包含tempInterface、tempService两个子工程,用户在需要创建新模块工程时,需把此工程及包含的子工程进行复制,并将“temp”关键字进行替换为具体的模块名,修改格式为xxxInterface、xxxService。 * 如果有多个模块,每个模块都有一个与“templateProj”相似的文件夹 ### tempInterface tempInterface是功能接口工程模板,所有的功能接口都在这里定义,以及一些跟实现无关的的类定义在这里。如:实体类、枚举类、异常类、定义的接口等等。 编写的接口结构如下: * com.southgis.ibase.xxx(模块名).service * Iyyy(功能名)Service.java * Izzz(功能名)Service.java * ... * 需要为每个功能类定义接口方法,并添加java doc注释 编写的实体类结构如下: * com.southgis.ibase.xxx(模块名).entity * yyy(实体类名)Entity.java * zzz(实体类名)Entity.java * ... * 需要为实体类添加持久化定义注解,包括创建索引的注解 ### tempService tempService是功能实现工程模板,实现工程依赖接口工程,其主要作用是实现接口工程的功能。 编写的实现类结构如下: * com.southgis.ibase.xxx(模块名).service * yyy(功能名)Service.java * zzz(功能名)Service.java * ... * 需要为每个定义的接口实现具体功能,一般完成数据的增删改查。 * 对于增删改操作,需要添加spring的事务注解: ```java org.springframework.transaction.annotation.Transactional ``` 编写的持久化类结构如下: * com.southgis.ibase.xxx(模块名).dao * Iyyy(实体类名)Dao.java * Izzz(实体类名)Dao.java * ... * 使用的是Spring Data模板方式,继承于PagingAndSortingRepository,即有常用的查询操作方法。 * 使用@Query或命名规范的方法定义,即可实现需要的查询操作。 ## main 用于统一组织微服务的根目录,如果已存在,则不需要再创建,只需要修改此目录下的pom.xml中的子模块(module)列表,添加新的微服务工程即可。 ### tempWeb 用户在需要创建新微服务工程时,需把此工程进行复制,并将“temp”关键字进行替换为具体的微服务名,修改格式为xxxWeb。 * 如果需要在已存在的微服务中添加模块功能,只需在微服务工程中添加相应模块的实现层(Service)依赖。 * 本模板微服务工程已默认依赖模板工程的实现,需要视情况进行删除或改名。 **springBoot启动类**: * com.southgis.ibase * WebApplication.java(启动类) **springBoot配置类**: * com.southgis.ibase.config(在该包下的类均为spring配置类) * BeansConfigurationXxx.java(本服务特定的bean加载配置) * EntityManageConfiguration.java(配置了注解扫描的包,以及数据库相关的参数注入) **【其中】** > 1. WebApplication启动类,应配置那些与部署环境有关的Bean,典型的比如服务调用类WebClient.Builder(或RestTemplate),而与业务相关的Bean不要配置在此文件中(因为在多个war包合并为一个war包时,会替换此类文件)。 > 2. BeansConfigurationXxx类名,需要根据当前微服务名调整名字,应配置那些与本服务相关的业务Bean(如果有),因为通用的Bean(比如:是否登录的验证)已通过依赖默认配置,所以不需要在此类中配置这些通用Bean。 > 3. EntityManageConfiguration默认数据源配置,如果使用多数据源,则应另外创建一个数据源的配置类,而不要与默认数据源配置混在此文件中(因为在多个war包合并为一个war包时,会替换此类文件) 服务调用类: * com.southgis.ibase.xxx(微服务名).web * xx1(模块1名)Conteoller.java * xx2(模块2名)Conteoller.java * ... * 一个微务服下可以包含多个模块,每个模块使用一或两个控制层类(查询和管理,可以分开到两个Controller) 配置文件: * src/main/resources * application.yml (配置文件) * 注册中心相关参数(eureka) * eureka.client.enabled(是否进行注册) * eureka.client.serviceUrl.defaultZone(注册的eureka服务器url) * 配置中心相关参数(apollo) * apollo.bootstrap.enabled (设置在应用启动阶段就加载 Apollo 配置) * apollo.bootstrap.namespaces(注入 namespace) * apollo.bootstrap.eagerLoad.enabled(将 Apollo 配置加载提到初始化日志系统之前,需要托管日志配置时开启) * logback-custom.xml(日志相关输出配置) * META-INF * app.properties(启动配置文件,主要设置“配置中心”相关信息) * spring.factories(spring优先扫描的类写在里面,写类全称) **【其中】** > 1. application.yml中,这些配置将是通用配置,如果有微服务自己的特定配置,应使用新的配置文件实现(因为在多个war包合并为一个war包时,会替换此类文件),然后在“BeansConfigurationXxx”配置类(或其他特定配置类)中通过@PropertySource注解引入。如: ``` package com.southgis.ibase.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import lombok.Getter; import lombok.Setter; @Getter @Setter @Configuration @PropertySource("classpath:application-flow.properties") public class FlowConfig { @Value("${flow.engine.name:}") private String engineName; } ``` ***注:Spring Boot 2.1.X版本的默认实现只支持properties格式配置,如果需要支持yml格式配置,需自行实现配置工厂类,参见:https://www.jianshu.com/p/ce98dad48e2b*** > 2. logback-custom.xml应统一配置,暂不需要特殊配置 Web配置文件: * src/main/webapp/WEB-INF * web.xml * 主要web工程的基本配置,在打包为war时并用tomcat容器时需要,jar包启动用不上。 **【其中】** > web.xml主要用于tomcat容器的外部打包(war),已无具体配置内容,也不需要设置具体配置(因为在多个war包合并为一个war包时,会替换此类文件) ### tempWebClient 为了方便服务间调用,针对消费者对本服务的调用进行封装,在需要的调用的工程中,添加此依赖,完成具体调用即可。 同时,为了兼容服务调用(即通过http协议调用本服务的方法)与功能调用(即通过注入本服务实现层模块tempService,调用功能实现原生方法)的切换,对服务调用方式再进行了tempInterface的浅封装,每个接口方法直接调用服务方法封装类,实现调用逻辑。 本模板工程使用FeignClient注解封装具体服务调用逻辑。 **服务调用封装类**: * com.southgis.ibase.temp.proxy * ITempServiceClient(利用@FeignClient实现服务调用) * META-INF/spring.factories(自动配置类加载描述文件) **接口层封装类**: * com.southgis.ibase.temp.proxy * TempServiceWrap(对功能接口的浅封装,调用者可以忽略调用的差异) **自动配置注入服务调用封装类**: * com.southgis.ibase.temp.config * ClientAutoConfiguration(按条件注入封装类,即在有原生功能实现类时,不注入此类) ### 启动微服务的配置 在启动微服务时,会自动找注册中心完成服务注册,并自动找配置中心完成配置的更新。在更新配置信息时,优先使用配置中心获取的配置,然后再使用本地的配置(application.yml)。 在本地开发调试时,需要视情况进行配置的调整。 1、禁用配置中心的配置,这样仅使用本地配置文件中的配置来测试更合适 (application.yml) ```yml apollo: bootstrap: enabled: false ``` 2、用不同注册中心时的处理: 2.1 使用本地的注册中心,调整pom.xml中的eureka-url参数值如下: (前提是在本地已启动了eureka服务) ```xml http://localhost:8001/eureka/ ``` 并确保application.yml的eureka是可用 ```yml eureka: client: enabled: true ``` 2.2 使用测试服务器的注册中心, * 调整application.yml,修改应用名,添加“-dev”后缀(以示此服务为本地开发用),如果某个服务在多人同时测试时,再添加“-开发人id”后缀(以示不同开发人员启用的服务) **【注意】必须调整,否则会影响其他服务的正常使用** ```yml spring: application: name: filemgr-dev ``` 可能多个人用时,添加开发人id,如: ```yml spring: application: name: flowengine-dennis ``` 并确保eureka是可用 ```yml eureka: client: enabled: true ``` * 调整pom.xml中的eureka-url参数值如下: ```xml http://192.168.10.126:9001/eureka/ ``` 3、检查其他配置正确,主要确保缓存服务与数据库服务地址: 3.1 redis自己安装了服务 ```yml redis: host: localhost ``` 3.2 redis使用128的服务,应调整数据库索引号(1~15之间) ```yml redis: default: database: 10 ``` 3.3 数据库连接设置正确: ```yml datasource: driver-class-name: aaa url: bbb username: ccc password: ddd jpa: database: eee properties: hibernate: default_schema: fff dialect: ggg ``` --- # 模板使用 ## 整体修改描述 1、调整文件夹名,将temp、xxx等占位符内容替换为服务名或模块名 2、调整pom.xml内的group、artifactId内容,将temp、xxx等占位符内容替换为服务名或模块名 3、调整类名,将temp、xxx等占位符内容替换为服务名或模块名 4、调整application.yml内容,将temp、xxx等占位符内容替换为服务名,及修正一些地址/端口号的配置信息 4、删除实体类*TempEntity.java*、功能接口类*ITempService.java*、功能实现类*TempService.java*、存贮类*ITempDao.java*、服务调用类*TempController.java*(或按实际需求修正定义) ## 复制springboot_template整个目录 1、然后将sample整个目录删除 2、删除.git、.settings、.project(如果有) 3、修改工程名称 将文件夹springboot_template改名为微服务名,如:filemgr 4、调整pom.xml (1)修改groupId为com.southgis.ibase.xxx(xxx指服务名,修改后的工程名小写) (2)修改artifactId为xxxApp(修改后的工程名) (3)根据项目需求修改version版本。 (4)修改modules,把templateProj改成xxx(下文件所述的如:fileShare) ## 修改模块组织工程templateProj 1、修改工程名称 将文件夹templateProj改名为模块名,如:fileShare 2、修改工程下的pom.xml (1)修改groupId为com.southgis.ibase.xxx(修改后的工程名小写) (2)修改artifactId为xxxModule(修改后的工程名) (3)根据项目需求修改version版本。 (4)修改modules,把tempInterface改成xxxInterface; 把tempService改成xxxService ## 修改模块接口工程tempInterface 1、修改文件夹名称为xxxInterface(修改后的工程名) 2、修改xxxInterface工程下的pom.xml (1)修改groupId为com.southgis.ibase.xxx(修改后的工程名小写) (2)修改artifactId为xxxInterface(修改后的工程名) (3)修改name为xxxInterface(修改后的工程名) 4、修改工程的代码结构 (1)根据上述描述的包结构方式修改包名,如:com.southgis.ibase.xxx(模块名).service (2)根据上述描述的接口名结构修改接口类名,如:Ixxx(功能名)Service.java ## 修改模块实现工程tempService 1、修改文件夹名称为xxxService(修改后的工程名) 2、修改xxxService工程下的pom.xml (1)修改groupId为com.southgis.ibase.xxx(修改后的工程名小写) (2)修改artifactId为xxxService(修改后的工程名) (3)修改name为xxxService(修改后的工程名) (4)修改依赖包 把原来的依赖tempInterface,改成依赖xxxInterface (5)根据上述描述的包结构方式修改包名,如:com.southgis.ibase.xxx(模块名).service 4、修改工程的代码结构 (1)根据上述描述的包结构方式修改包名,如:com.southgis.ibase.xxx(模块名).service (2)根据上述描述的接口名结构修改接口类名,如xxx(功能名)Service.java 5、修改单元测试的代码结构 (1)在单元测试目录src/test/java下,存在两个子目录: dev,是开发人员写的单元测试代码,是测试类的包根名; test,是测试人员写的单元测试代码,是测试类的包根名。 (2)开发人员需要写单元测试,测试类以dev为包的根名,如: dev.com.southgis.xxx.service.AAA_Test ## 修改服务组织工程main 1、不用修改工程文件夹名称 2、修改工程下的pom.xml (1)修改groupId为com.southgis.ibase.xxx(修改后的工程名小写) (2)修改artifactId为xxxMain(修改后的工程名) (3)根据项目需求修改version版本 (4)修改modules,把tempWeb改成xxxWeb ## 修改微服务工程tempWeb 1、修改文件夹名称为xxxWeb(修改后的工程名) 2、修改xxxWeb工程下的pom.xml (1)修改groupId为com.southgis.ibase.xxx(修改后的工程名小写) (2)修改artifactId为xxxWeb(修改后的工程名) (3)修改name为xxxWeb(修改后的工程名) (4)修改依赖包 把原来的依赖tempService,改成依赖xxxService (5)修改build下的finalName为xxxweb 3、修改resources/application.yml或修改resources/application.properties (1)修改resources/application.yml,修改内容如下(推荐): ```yml spring: application: name: xxxWeb module: name: xxx/xxxWeb ``` 4、修改resources/META-INF/app.properties,修改内容如下: app.id=xxxWeb 5、修改src/main/webapp/WEB-INF/web.xml 把display-name的属性值改成xxxWeb 6、修改工程的代码结构 (1)根据上述描述的包结构方式修改包名,如:com.southgis.ibase.xxx(模块名).web (2)如果引入了本服务特有的Bean,将BeansConfigurationXxx类名根据当前微服务名调整名字,并启用此类定义(默认是注释的) (3)根据需要,添加更多的模块控制类(Controller) ## 修改微服务工程tempWebClient **注:此模板工程仅针对FeignClient的调用方式进行封装,其他RestTemplate或WebFlux的调用方式做类似封装即可** *主要区别在XxxServiceClient上,将此类改为对应的调用实现* 1、修改文件夹名称为xxxWeb(修改后的工程名) 2、修改xxxWeb工程下的pom.xml (1)修改groupId为com.southgis.ibase.xxx(修改后的工程名小写) (2)修改artifactId为xxxWebClient(修改后的工程名) (3)修改name为xxxWeb(修改后的工程名) (4)修改依赖包 把原来的依赖tempInterface,改成依赖xxxInterface 3、修改工程的代码结构 (1)根据上述描述的包结构方式修改包名,如:com.southgis.ibase.xxx(模块名).proxy (2)ITempServiceClient类名修改为XxxServiceClient,内部方法应该是本微服务被其他服务调用的方法封装 (3)TempServiceWrap类名修改为XxxServiceWarp,并实现上述描述接口IXxxService,内部方法视对服务调用的封装而定,未提供具体调用的,抛出UnsupportedOperationException异常即可。 (4)ClientAutoConfiguration中针对注入的Bean修正类名(如果有),同步调整META-INF/spring.factories中的自动配置包名 *注意,本类添加了条件注入,应同时修正条件类型为正确的接口类型IXxxService.class*