且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

cloud Alibaba电商后台组件实战:架构演进,了解领域驱动设计,项目公共模块编写(2)

更新时间:2021-11-03 19:07:35

E-commerce开发

实现公共模块

步骤


创建项目 -->导入依赖–>编写配置


父工程创建e-commerce-springcloud 导入需要的对应依赖


<?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.hyc.ecommerce</groupId>
    <artifactId>e-commerce-springcloud</artifactId>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>e-commerce-common</module>
        <module>e-commerce-mvc-config</module>
    </modules>

    <packaging>pom</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
    </parent>

    <properties>
        <!-- Spring Cloud Hoxton.SR8 依赖 -->
        <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
        <!-- spring cloud alibaba 依赖 -->
        <spring-cloud-alibaba.version>2.2.4.RELEASE</spring-cloud-alibaba.version>
    </properties>

    <dependencies>
        <!-- lombok 工具通过在代码编译时期动态的将注解替换为具体的代码,
        IDEA 需要添加 lombok 插件 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.4</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.6.0</version>
        </dependency>
        <!-- 引入jwt-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.10.5</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.10.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.10.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
    </dependencies>

    <!-- 项目依赖管理 父项目只是声明依赖,子项目需要写明需要的依赖(可以省略版本信息) -->
    <dependencyManagement>
        <dependencies>
            <!-- spring cloud 依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- spring cloud alibaba 依赖 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 配置远程仓库 -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>

公共子模块 公共库 commons

e-commerce-common 模块

依赖如下

<?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>e-commerce-springcloud</artifactId>
        <groupId>com.hyc.ecommerce</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>e-commerce-common</artifactId>

    <!-- 模块名及描述信息 -->
    <name>e-commerce-common</name>
    <description>通用模块</description>
</project>

这么模块之后会放入很多的数据模型,来给功能服务模块使用,这里先创建并且统一响应,之后会有对应的数据模型加入其中


创建响应格式


/**
 * @author : 冷环渊
 * @date : 2021/12/2
 * @context: 通用响应定义
 * {
 * "code":1
 * "message":hyc
 * "data":{}
 * }
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResponse<T> implements Serializable {
    //相应码
    private Integer code;
    //返回消息 信息描述
    private String message;

    public CommonResponse(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    //泛型内容数据
    private T Data;
}

公共子模块 web统一返回与全局异常处理 e-commerce-mvc-config

e-commerce-mvc-config这个模块主要是为了隔离功能,有的服务模块比如网关,不能有web依赖的启动,这样他导入commons就可以了,起到很好的服务对应功能隔离


依赖如下

<?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>e-commerce-springcloud</artifactId>
        <groupId>com.hyc.ecommerce</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>e-commerce-mvc-config</artifactId>
    <!-- 模块名及描述信息 -->
    <name>e-commerce-mvc-config</name>
    <description>通用配置模块</description>

    <dependencies>
        <!-- 引入 Web 功能 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.hyc.ecommerce</groupId>
            <artifactId>e-commerce-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

编写注解 IgnoreResponseAdvice


IgnoreResponseAdvice 忽略统一响应注解定义,就是不需要用我们定义的CommonsResponese的类使用这个注解就可以不使用


/**
 * @author : 冷环渊
 * @date : 2021/12/2
 * @context:忽略统一响应注解定义
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreResponseAdvice {

}

实现统一响应和统一忽略响应注解

/**
 * @author : 冷环渊
 * @date : 2021/12/2
 * @context: 实现统一响应和统一忽略响应注解
 * @params :  null
 * @return :  * @return : null
 */
@RestControllerAdvice(value = "com.hyc.ecommerce")
//实现响应体建议接口
public class CommonResponseDataAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter methodParameter,
                            Class<? extends HttpMessageConverter<?>> aClass) {
        //判断类上面有没有这个注解 IgnoreResponseAdvice
        if (methodParameter.getDeclaringClass().isAnnotationPresent(IgnoreResponseAdvice.class)) {
            return false;
        }
        //判断方法上有没有这个注解 IgnoreResponseAdvice
        if (methodParameter.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class)) {
            return false;
        }
        //都没有的话 就代表要使用公共返回格式
        return true;
    }

    //处理 如果是需要使用的话怎么用
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
                                  MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {
        //定义最终的返回对象
        CommonResponse<Object> response = new CommonResponse<>(0, "");
        //如果等于null就代表没有 直接返回
        if (o == null) {
            return response;
            //等于公共返回类型的 就把o转换成 公共返回 CommonResponse<>
        } else if (o instanceof CommonResponse) {
            response = (CommonResponse<Object>) o;
            //如果都不是的话 那就是响应内容 设置响应data 为这个object
        } else {
            response.setData(o);
        }
        return response;
    }
}

全局异常处理

GlobalExceptionAdvice 处理全局异常,只要出现了请求出现了异常给一个统一的返回结果


/**
 * @author : 冷环渊
 * @date : 2021/12/2
 * @context: 实现统一响应和统一忽略响应注解
 * @params :  null
 * @return :  * @return : null
 */
@RestControllerAdvice(value = "com.hyc.ecommerce")
//实现响应体建议接口
public class CommonResponseDataAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter methodParameter,
                            Class<? extends HttpMessageConverter<?>> aClass) {
        //判断类上面有没有这个注解 IgnoreResponseAdvice
        if (methodParameter.getDeclaringClass().isAnnotationPresent(IgnoreResponseAdvice.class)) {
            return false;
        }
        //判断方法上有没有这个注解 IgnoreResponseAdvice
        if (methodParameter.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class)) {
            return false;
        }
        //都没有的话 就代表要使用公共返回格式
        return true;
    }

    //处理 如果是需要使用的话怎么用
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
                                  MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {
        //定义最终的返回对象
        CommonResponse<Object> response = new CommonResponse<>(0, "");
        //如果等于null就代表没有 直接返回
        if (o == null) {
            return response;
            //等于公共返回类型的 就把o转换成 公共返回 CommonResponse<>
        } else if (o instanceof CommonResponse) {
            response = (CommonResponse<Object>) o;
            //如果都不是的话 那就是响应内容 设置响应data 为这个object
        } else {
            response.setData(o);
        }
        return response;
    }
}