The introduction
Most projects start out with efficiency, perhaps copying the original scaffolding and starting the business coding phase. This mode of rapid development is fine in the early stage, but as the business slowly expands, the technical debt in the early stage always needs to be paid. The version of the JAR package between services is difficult to unify due to different developers. Unified business processing classes may also be stored separately by each service. If the product has business changes, it also needs to search for modification everywhere, and a series of problems are troublesome. The rectification and optimization of the whole project is urgent. Here are some of my experiences in the optimization process.
Train of thought
The project is managed by Maven, which facilitates optimization. The idea of optimization is mainly to encapsulate and unify. Taking one of our projects as an example, it can be roughly divided into background management API service, front-end API service, back-end timer service and back-end message service. Before optimization, the JAR package versions of each service are all run successfully according to their preferences, and the public classes for handling entities are also stored in their util packages. After product modification, it needs to be modified by the person in charge of each service.
unified
The first step is to unify the version of the JAR package. This prevents service linkage from causing errors due to jar package problems. Knowing maven, you can package all the services into a single parent project as a multi-module multi-module project.
- shpping father (maven project) | -- pom. XML (project main pom file) | | - background management API | | - pom. The XML (pom) | | | - front-end API | -- pom. XML (pom) | | - The back-end timer | | - pom. XML (pom) |... And so onCopy the code
This optimization focuses on the configuration in the project master POM file. The configuration of each sub-POM needs to be taken into account. Here are some points that need to be noted.
<? The XML version = "1.0" encoding = "utf-8"? > < project XMLNS = "http://maven.apache.org/POM/4.0.0" XMLNS: xsi = "http://www.w3.org/2001/XMLSchema-instance" Xsi: schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion>4.0.0</modelVersion> <packaging> POm </packaging> // The name of module and the artifactId tag in your child POM file <module> Mc-core </module> <module> Mc-buy </module> <module> Mc-task </module>...... </modules> </groupId> <artifactId>shopping</artifactId> <version>0.0.1-SNAPSHOT</version> <name>shopping</name> <description> </description> < aliyun. Oss. Version > 3.4.0 < / aliyun. Oss. Version > < spring. The boot. Version > 2.2.6. RELEASE < / spring. The boot. Version >... </properties> </properties> </properties> </properties> </properties> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring.boot.version}</version> </dependency> ........ < / dependencies > / / relative to the dependencies, dependencyManagement just states rely on, does not introduce, so components need to display statement to rely on. // If the dependency is not declared in the child project, it is not inherited from the parent project. // The dependency is inherited from the parent project only if the dependency is written in the child project and the specific version is not specified. // If the version number is specified in the subproject, the jar version specified in the subproject will be used. <dependencyManagement> <dependencies> <! --> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId> <version>${aliyun.oss.version}</version> </dependency> ........ </dependencies> </dependencyManagement> </project>Copy the code
With some definitions for the master POM file, let’s take a quick look at some definitions for the child POM file.
<? The XML version = "1.0" encoding = "utf-8"? > < project XMLNS = "http://maven.apache.org/POM/4.0.0" XMLNS: xsi = "http://www.w3.org/2001/XMLSchema-instance" Xsi: schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion>4.0.0</modelVersion> // Specify the coordinates of the master POM so that they can be linked <parent> <artifactId>shopping</artifactId> <groupId>cn. MC </groupId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId> Mc-buy </artifactId> <name> Mc-buy </name> <description> API </description> <dependencies> <dependency> <dependency> Com.github. Pagehelper <dependency> <dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> </dependency> ....... </dependencies>Copy the code
Step 2 Unify configuration files To prevent version inconsistency caused by inconsistent configuration files. Now that the project is integrated through Maven, we will create a new service Module dedicated to the common configuration. The method of creating a new Module is unnecessary. We’ll mark it as a Maven project after we create it. The project structure is as follows:
- shpping father (maven project) | -- pom. XML (project main pom file) | | - background management API | | - pom. The XML (pom)...... | | - core core packages | | SRC | | Java / / hold unified class | | resources / / hold unified configuration file | | application - core - dev | | | application - core - pro | application - the core - the test | | - pom. The XML (pom)Copy the code
As you can see, we created a new core package. Under the Resources package, we can create a new configuration file. Because it is convenient for environment testing, we created three environment dev, pro and test, corresponding to the local machine, production and test respectively. At this point we go back to the Module where we need to import configuration, such as the background administration API, in the YML file.
spring:
profiles:
include: core-dev
Copy the code
To read the configuration of core-dev. Similarly, core-Pro can be configured to read the configuration of application-core-Pro. In this unified configuration file, you can put some redis, MQ, and other services that use unified configuration.
In conclusion, the two consistent optimization can make the JAR packages of the service uniform. When the same configuration is used in the project, the unified configuration file is introduced and the configuration file is unified.
encapsulation
Common code encapsulation for projects is also important.
In order to unify the configuration file, we created a module-core core package. This package can not only help us unify the configuration, but also we can write the processing class that each service needs to reference in its Java package, which can be introduced into each service as a core JAR package. For example, some services need a date-handling class, so we write one in the Core packageDateUtil
Class. Introduce core JARS into the required services
<! --> <dependency> <groupId>cn. MC </groupId> <artifactId> Mc-core </artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>Copy the code
We can use the DateUtil class, and when it needs to be modified, we just need to modify it and re-upload the core package via MVN install to update the utility class for each service that references the Core package. It’s pretty handy, but if you’re writing it in the old way and you need to modify multiple utility classes, it’s easy to miss things.
Through the hole
Multi-module projects are a very useful way to manage them. I summarize two problems I have encountered.
- If a submodule adds a class or modifs a class, it needs to be reinstalled so that the imported module can receive updates to the JAR, including configuration files. Although there is no problem compiling locally, packaging as a JAR will not work without install.
- If the main POM file adds a JAR file, you need to install the entire parent project, otherwise the child project will not find the JAR package.
conclusion
When the project has a lot of business, we should consider the way to unify various functions so that the development energy can be focused on the business implementation, otherwise a small change will affect a lot of legacy bugs, so if your company’s project also has this problem, it is still suggested that the long pain is better than the short pain.