⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/weixin_44213308/article/details/111151350 「<每天一点>」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

1、背景

首先,谈一谈什么是“springBoot业务组件化开发”,最近一直在开发一直面临这一个问题,就是相同的业务场景场景在一个项目中使用了,又需要再另外一个项目中复用,一遍又一遍的复制代码,然后想将该业务的代码在不同的项目中维护起来真的很难。

最开始想用微服务的方式来解决这个问题,但是觉得一套完整的微服务太重,而且目前微服务还处于振荡期(去年的微服务解决方案,今年国内直接都换成了阿里的技术解决方案),此外很多时候我们接私活,就是个单体的springboot项目,用不上微服务这种级别的项目,所以想来想去这条路不是很满足我的需求;再后来,想到单体的聚合架构,但是聚合架构的项目,个人觉得有时候也不是很好,一般的聚合项目就是基于某个具体实例架构下才能使用,换一个架构自己写的业务model就不能用了(比如你在suoyi框架下开发的模块业务包,在guns下可能就直接不能使用了)。

最后,想了一下,能不能单独开发一个项目,这个项目可以自己独立运行(微服务架构下用),也可以在单体项目中直接通过pom引入的方式,然后简单的配置一下,然后直接使用多好;查了一下网上没有现成的技术解决方案,问了同事,他说我这种思想属于SOA的一种实现,同时有第三包和聚合项目的影子在里面。也许有什么更好的技术解决方案,也希望各位能够不吝赐教。

补充一句,之所以说“业务组件化”开发,来源于Vue的思想,希望Java后端开发的业务也可像vue的组件一样去使用,这样多好

2、demo

2-1项目准备

①建一个Java项目项目,结构如下图:

②pom文件如下:

<?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 http://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.3.1.RELEASE</version>
</parent>

<groupId>top.wp</groupId>
<artifactId>cx-flow</artifactId>
<version>1.0-SNAPSHOT</version>


<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<mysql-connector-java.version>8.0.17</mysql-connector-java.version>
<druid.version>1.1.21</druid.version>
<mp.version>3.3.2</mp.version>
<fastjson.version>1.2.70</fastjson.version>
<jwt.version>0.9.1</jwt.version>
<hutool.version>5.3.7</hutool.version>
<lombok.versin>1.18.12</lombok.versin>
<swagger.version>2.9.2</swagger.version>
<swagger.bootstrap.ui.version>1.9.6</swagger.bootstrap.ui.version>
<easypoi.version>4.2.0</easypoi.version>
<jodconverter.version>4.2.0</jodconverter.version>
<libreoffice.version>6.4.3</libreoffice.version>
<justauth.version>1.15.6</justauth.version>
<aliyun.oss.version>3.8.0</aliyun.oss.version>
<qcloud.oss.version>5.6.23</qcloud.oss.version>
<aliyun.sms.sdk.version>4.4.6</aliyun.sms.sdk.version>
<aliyun.sms.esc.version>4.17.6</aliyun.sms.esc.version>
<qcloud.sms.sdk.version>3.1.57</qcloud.sms.sdk.version>
</properties>


<dependencies>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mp.version}</version>
</dependency>

<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>

<!--数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>

<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>

<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.versin}</version>
</dependency>

</dependencies>


<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- <excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.xml</exclude>
</excludes> -->
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.yml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>


</project>

③配置文件如下:主要是数据库和mybaits-plus的配置(其实可以不用这个配置文件,在这只是为了项目能够独立运行起来)

#服务配置
server:
port: 8080
#spring相关配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/cx-xn?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true
username: 数据库账户
password: 数据库密码
servlet:
multipart:
max-request-size: 100MB
max-file-size: 100MB
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss.SSS
locale: zh_CN
serialization:
# 格式化输出
indent_output: false

#mybaits相关配置
mybatis-plus:
mapper-locations: classpath*:top/wp/cx/**/mapping/*.xml, classpath:/META-INF/modeler-mybatis-mappings/*.xml
configuration:
map-underscore-to-camel-case: true
cache-enabled: true
lazy-loading-enabled: true
multiple-result-sets-enabled: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

global-config:
banner: false
db-config:
id-type: assign_id
table-underline: true
enable-sql-runner: true
configuration-properties:
prefix:
blobType: BLOB
boolValue: TRUE

④启动入口(可以不用写,启动入口存在目的是让项目可以自己跑起来)

package top.wp.cx;

import cn.hutool.log.StaticLog;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CXApplication {
public static void main(String[] args) {
SpringApplication.run(CXApplication.class, args);
StaticLog.info(">>> " + CXApplication.class.getSimpleName() + " 启动成功!");

}
}

⑤测试:entity、result

package top.wp.cx.modular.test.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;


@Data
@TableName("test")
public class Test {

/**
* 主键
*/
@TableId(type = IdType.ASSIGN_ID)
private Integer id;

/**
* 账号
*/
private String name;

}
package top.wp.cx.modular.test.result;

import lombok.Data;
@Data
public class TestResult {

private Integer id;

private String name;

}

⑥测试mapper、xml、service和controller

package top.wp.cx.modular.test.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import top.wp.cx.modular.test.entity.Test;

/**
* 系统用户数据范围mapper接口
*
* @author xuyuxiang
* @date 2020/3/13 15:46
*/
//@Mapper
public interface TestMapper extends BaseMapper<Test> {
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.wp.cx.modular.test.mapper.TestMapper">

</mapper>
package top.wp.cx.modular.test.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import top.wp.cx.modular.test.entity.Test;
import top.wp.cx.modular.test.mapper.TestMapper;

/**
* 一个service实现
*
* @author yubaoshan
* @date 2020/4/9 18:11
*/
@Service
public class TestService extends ServiceImpl<TestMapper, Test> {

}
package top.wp.cx.modular.test.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.wp.cx.modular.test.entity.Test;
import top.wp.cx.modular.test.service.TestService;

import javax.annotation.Resource;
import java.util.List;

/**
* 一个示例接口
*
* @author yubaoshan
* @date 2020/4/9 18:09
*/
@RestController
@RequestMapping("/test")
public class TestController {

@Resource
private TestService testService;

@GetMapping("")
public List<Test> testResult(){
return testService.list();
}

@GetMapping("/2")
public String testResult2(){
return "22";
}
}

至此项目准备完成,其实就是简单见了一个测试项目,此时如果你按照上面的步骤,写了启动类和配置项信息,项目是可以独立运行的。

2-2项目打包、引入、运行

①将2-1中的测试项目进行打包:install右键第一个选项

②此时你的本地maven仓库会出现刚才的项目(当然前提是你的idea配置过本地的maven)

③新建另外一个项目cx-main

④pom文件如下:注意将你刚才的准备测试的项目引入进来

<?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 http://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.3.1.RELEASE</version>
</parent>

<groupId>top.wp.cx</groupId>
<artifactId>cx-main</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<mysql-connector-java.version>8.0.17</mysql-connector-java.version>
<druid.version>1.1.21</druid.version>
<mp.version>3.3.2</mp.version>
<fastjson.version>1.2.70</fastjson.version>
<jwt.version>0.9.1</jwt.version>
<hutool.version>5.3.7</hutool.version>
<lombok.versin>1.18.12</lombok.versin>
<swagger.version>2.9.2</swagger.version>
<swagger.bootstrap.ui.version>1.9.6</swagger.bootstrap.ui.version>
<easypoi.version>4.2.0</easypoi.version>
<jodconverter.version>4.2.0</jodconverter.version>
<libreoffice.version>6.4.3</libreoffice.version>
<justauth.version>1.15.6</justauth.version>
<aliyun.oss.version>3.8.0</aliyun.oss.version>
<qcloud.oss.version>5.6.23</qcloud.oss.version>
<aliyun.sms.sdk.version>4.4.6</aliyun.sms.sdk.version>
<aliyun.sms.esc.version>4.17.6</aliyun.sms.esc.version>
<qcloud.sms.sdk.version>3.1.57</qcloud.sms.sdk.version>
</properties>


<dependencies>

<dependency>
<groupId>top.wp</groupId>
<artifactId>cx-flow</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mp.version}</version>
</dependency>

<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>

<!--数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>

<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>

<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.versin}</version>
</dependency>

</dependencies>


<!--xml打包排除-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- <excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.xml</exclude>
</excludes> -->
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.yml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>

</project>

⑤application.yml配置文件 注意xml的扫描

#服务配置
server:
port: 8081
#spring相关配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/cx-xn?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT&nullCatalogMeansCurrent=true
username: root
password: root
servlet:
multipart:
max-request-size: 100MB
max-file-size: 100MB
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss.SSS
locale: zh_CN
serialization:
# 格式化输出
indent_output: false

#mybaits相关配置
mybatis-plus:
#xml文件扫描
mapper-locations: classpath*:top/wp/cx/**/mapping/*.xml, classpath:/META-INF/modeler-mybatis-mappings/*.xml
configuration:
map-underscore-to-camel-case: true
cache-enabled: true
lazy-loading-enabled: true
multiple-result-sets-enabled: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

global-config:
banner: false
db-config:
id-type: assign_id
table-underline: true
enable-sql-runner: true
configuration-properties:
prefix:
blobType: BLOB
boolValue: TRUE

⑥启动入口,注意spring和mapper扫描

package top.wp.cx.main;

import cn.hutool.log.StaticLog;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = {"top.wp.cx.modular.test"}) // spring扫描
@MapperScan(basePackages = {"top.wp.cx.modular.test.**.mapper"}) // mybatis扫描mapper
public class CXApplication {
public static void main(String[] args) {
SpringApplication.run(CXApplication.class, args);
StaticLog.info(">>> " + CXApplication.class.getSimpleName() + " 启动成功!");
}
}

⑦此时启动cx-main的项目,访问2-1的测试controller能访问成功证明配置正确

文章目录
  1. 1. 1、背景
  2. 2. 2、demo
    1. 2.1. 2-1项目准备
    2. 2.2. 2-2项目打包、引入、运行