【笔记】Springboot自定义starter项目实践

starter的加载原理:

springboot工程一般都是通过入口类Application启动项目,根据对应目录下的xml、yml、注解等配置文件初始化相关的配置和实例化相关的bean放入IOC容器进行管理(约定大于配置),还会将依赖的starter的相关bean实例化放入容器进行统一管理(自定义starter的开箱即用,无需重复进行相关配置)。


工作场景

在工作中使用微服务架构,以前DAO持久层使用的是mybatis在很多微服务模块都有独立引入mybatis的依赖,时间久了出现mybatis在不同微服务版本不一致导致的兼容性问题。现在有时间我就将DAO层相关依赖抽离并封装成一个starter给各个微服务依赖,还支持mybatis-plus的高级功能,实现了模块之间的松耦合,统一管理版本号。


实现分析:

提示:自定义starter基础我就不细说了,懂得都懂

【笔记】Springboot自定义starter项目实践_第1张图片
【笔记】Springboot自定义starter项目实践_第2张图片

创建公共模块common

采取父子工程项目结构,父工程统一管理公共的依赖和boot版本号,子工程直接使用父工程对应版本的依赖

父工程common的pom.xml

<?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>

    <groupId>com.ibatis</groupId>
    <artifactId>common-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>common-dao</module>
        <module>common-dao-starter</module>
    </modules>

    <properties>
        <boot-version>2.6.7</boot-version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>${boot-version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.5.2</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

创建公共服务common-dao

【笔记】Springboot自定义starter项目实践_第3张图片

common-dao的pom.xml

<?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">
    <parent>
        <artifactId>common-demo</artifactId>
        <groupId>com.ibatis</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>common-dao</artifactId>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
    </dependencies>
</project>

这个模块主要是配置mybatis-plus的相关配置,比如BaseEntity管理一些基础字段

package com.ibatis.common.dao.entity;

import com.baomidou.mybatisplus.annotation.*;

import java.io.Serializable;
import java.util.Date;

public abstract class BaseEntity implements Serializable {
    @TableId(type = IdType.AUTO)
    private Long id;
    @TableField(fill = FieldFill.INSERT)
    private Long operatorId;
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    @TableField(fill = FieldFill.INSERT)
    @TableLogic
    private int deleteFlag;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getOperatorId() {
        return operatorId;
    }

    public void setOperatorId(Long operatorId) {
        this.operatorId = operatorId;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public Integer getDeleteFlag() {
        return deleteFlag;
    }

    public void setDeleteFlag(Integer deleteFlag) {
        this.deleteFlag = deleteFlag;
    }
}

字段填充处理器MybatisFillHandler

package com.ibatis.common.dao.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;

import java.util.Date;

public class MybatisFillHandler implements MetaObjectHandler {
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject , "createTime" , Date::new , Date.class);
        this.strictInsertFill(metaObject , "updateTime" , Date::new , Date.class);
    }

    public void updateFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject , "updateTime" , Date::new , Date.class);
    }
}

创建公共服务common-dao-starter

【笔记】Springboot自定义starter项目实践_第4张图片

common-dao-starter的pom.xml,这里依赖common-dao的相关配置类

<?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">
    <parent>
        <artifactId>common-demo</artifactId>
        <groupId>com.ibatis</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>common-dao-starter</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.ibatis</groupId>
            <artifactId>common-dao</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>2.6.7</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.19</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.20</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
    </dependencies>
</project>

mybatis相关配置类MybatisConfig,这里demo使用了mybatis-plus的多租户tenant插件和属性自动填充处理器handler

package com.ibatis.common.dao.starter.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.ibatis.common.dao.handler.MybatisFillHandler;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;


@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
public class MybatisConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //多租户插件
        interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
            public Expression getTenantId() {
                //测试默认1
                return new LongValue(1);
            }

            //过滤白名单
            public boolean ignoreTable(String tableName) {
                //测试用户表以外租户隔离
                return !"user".equals(tableName);
            }
        }));

        //分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

    @Bean
    public MybatisFillHandler mybatisFillHandler(){
        return new MybatisFillHandler();
    }
}

spring.factories对config进行被动注册:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ibatis.common.dao.starter.config.MybatisConfig

其他服务demo-boot使用common-dao-starter

【笔记】Springboot自定义starter项目实践_第5张图片

demo-boot的pom.xml,依赖common-dao-starter免去重复配置(开箱即用)

<?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.6.7</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo-boot</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo-boot</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>
		</dependency>

		<dependency>
			<groupId>com.ibatis</groupId>
			<artifactId>common-dao-starter</artifactId>
			<version>1.0-SNAPSHOT</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

application.properties配置数据源相关信息

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/liang?useSSL=FALSE&serverTimezone=UTC&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=

entity-User.java

package com.example.demoboot.entity;

import com.ibatis.common.dao.entity.BaseEntity;

public class User extends BaseEntity {
    private Long tenantId;
    private String name;

    public Long getTenantId() {
        return tenantId;
    }

    public void setTenantId(Long tenantId) {
        this.tenantId = tenantId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

mapper-UserMapper.java

package com.example.demoboot.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demoboot.entity.User;

public interface UserMapper extends BaseMapper<User> {

}

UserMapper.xml

<?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="com.example.demoboot.mapper.UserMapper">

</mapper>

UserService

package com.example.demoboot.service;

import com.example.demoboot.entity.User;
import com.example.demoboot.mapper.UserMapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
@RequestMapping("/user")
public class UserServiceImpl {

    @Resource
    private UserMapper userMapper;

    @GetMapping("get-all-user")
    public List<User> getAllUser() {
        return userMapper.selectList(null);
    }
}


测试结果:

模拟数据:插入2条用户信息

【笔记】Springboot自定义starter项目实践_第6张图片

使用postman接口调用测试是否正常使用

【笔记】Springboot自定义starter项目实践_第7张图片

接口调用正常

你可能感兴趣的:(Java基础,spring,boot,mybatis,java,jar)