以前做的项目比较小,一般一个工程就是一个项目,各个模块的相同代码可以抽取为Base代码,比如BaseService.java里面可以抽取一些基础的增删改查函数;现在项目较大需要使用多个工程来构成一个项目,那么多个工程之间其实也有些代码是相同的,在每个工程里面复制维护相同的基础代码?还是将这些相同的基础代码抽取出来呢?还以BaseService为例,我是将这样的代码单独放到一个工程里面,然后在其他工程中使用maven进行依赖这个公共的工程,怎么样比起每个工程复制维护相同的BaseService代码是不是合理了一些呢?我在操作的过程中还是有些坑在这里总结一下。
业务代码就不放了,我以简单的demoA、demoB来进行说明吧,如何将demoA依赖到demoB,然后顺利的打包demoB并能够在demoB中运行demoA中的代码,这两个工程都是使用springboot进行构建的。
demoA中写了个UserServiceImpl类只有一个方法say,在该方法中返回字符串,其实在springboot项目中会自动产生启动函数,我已将其删除(原因后续说),代码如下:
demoA的pom文件如下,我把其中springboot工程自动生成的plugin插件配置注释掉了,原因后续说明:
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demoA</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demoA</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<!--
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
-->
</plugins>
</build>
</project>
demoB工程就比较中规中矩了,包含main启动类和pom中的plugin,我在demoB中写了个UserController,并注入了demoA里面的UserServiceImpl,代码如下:
在demoB的pom里面引入了demoA的坐标
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demoB</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demoB</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>demoA</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
这样编码完成之后在demoB中可能会出现红色错误提示(找不到demoA中的UserServiceImpl类),需要对demoA工程进行maven build install,这样在本地仓库中就能看到demoA了,然后对demoB进行maven update操作这样demoB中刚才的错误就消失了,此时对demoB执行maven build install就ok了,通过java -jar命令运行demoB的jar文件,访问成功
其实我在最初搭建的时候并没有成功,我的坑是出现在了demoA上面,在demoA的pom中并没有注释掉默认的plugin也没有删掉main启动类,这种情况下在eclipse中直接运行demoB也是没有问题的,对demoA进行maven build install也没有问题(在本地仓库也能看到安装成功),但是在对demoB进行maven build install时则出现了引用失败的提示
原因是这两个工程都使用了springboot的打包插件,解决办法就是删除demoA中spring-boot-maven-plugin插件(删掉这个plugin之后main函数就没有意义了,可同时删除main启动类),因为这个SpringBoot插件会在Maven的package后进行二次打包,目的为了生成可执行jar包,如果demoA中定义了这个插件,则必须有main启动函数,所以此处直接删掉了springboot插件和main启动类。
总结:
被引入的spring boot jar 包不能引入spring-boot-maven-plugin ,否则引入此jar包的项目编译时会报 找不到程序包 的错误