前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用Spring Cloud Alibaba构建用户中心!只要5分钟

用Spring Cloud Alibaba构建用户中心!只要5分钟

作者头像
田维常
发布2022-06-13 09:16:42
2670
发布2022-06-13 09:16:42
举报

Java 面试辅导来啦!田哥和你面对面,一对一 规划如何准备面试、如何与面试官对话。涵盖内容有:修改简历一对一模拟面试、常见八股文、25w字面试小抄项目实战源码分析等优质内容。 更新汇总: https://www.yuque.com/cwnait/sxhgy9/kyqm2r

你好,我是田哥。前几天,有几位朋友私信我,叫我写一个使用Spring Cloud Alibaba 搭建项目。

今天,我给安排上,使用Spring Cloud Alibaba 搭建一个用户中心。

下面,我就来给大家说一下,我饿还是如何搭建的,具体步骤如下:

  • 使用IDEA创建项目结构
  • 添加maven相关依赖
  • 安装Nacos
  • 业务代码

整个技术栈:Spring Boot+Dubbo+Nacos+MyBatis+MySQL

创建项目结构

我们先来创建父项目user-center,打开IDEA,进入File菜单。

然后,选择next

如果你的ArtifactId太长了,其中很多单词使用-分割,那在这里最好把你的复制一遍,后面有用。

选择好自己的maven和本地仓库配置文件setting.xml

点击finish,那么一个简单的项目就创建了。

下面我们来创建modules

和前面一样

这里我们需要填写自己的module名称,比如:user-web或者user-service或者 user-api

然后就是next、next、最后就是finish(注意项目名称使用-的情况,和尚庙创建父项目一样)。

同理,我们可以通过上面的方法创建对应的module。

注意:我们的父项目user-center不做任何业务相关,所以,我们需要把父项目user-center中的src目录给删除。

然后,整个项目就变成了:

添加maven依赖

我们使用父项目进行版本管理,即user-center中的pom.xml内容如下:

代码语言:javascript
复制
<?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>
    <packaging>pom</packaging>
    <modules>
        <module>user-web</module>
        <module>user-service</module>
        <module>user-api</module>
    </modules>

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

    <groupId>com.tian</groupId>
    <artifactId>user-center</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>user-center</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
        <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <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>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

user-api主要给服务消费者和服务提供者共同使用那部分代码,也就是提供给外部的api和相关共用代码。

user-api中pom.xml内容:

代码语言:javascript
复制
<?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>com.tian</groupId>
        <artifactId>user-center</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>user-api</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>user-api</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
</project>

user-service是业务具体实现

user-service中pom.xml内容:

代码语言:javascript
复制
<?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>com.tian</groupId>
        <artifactId>user-center</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>user-service</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>user-service</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.59</version>
        </dependency>
        <!-- 把user-api引进来-->
        <dependency>
            <groupId>com.tian</groupId>
            <artifactId>user-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.8.3</version>
        </dependency>
    </dependencies>
</project>

user-web是用户管理的页面系统

user-web中的pom.xml内容:

代码语言:javascript
复制
<?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>com.tian</groupId>
        <artifactId>user-center</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>user-web</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>user-web</name>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.56</version>
        </dependency>
        <dependency>
            <groupId>com.tian</groupId>
            <artifactId>user-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

以上就是整个项目的整体结构。

代码语言:javascript
复制
user-center
|--user-api
|--user-service
|--user-web

项目整体结构以及搭建完成,我们现在把Nacos server端给搞定。

Nacos 安装

Nacos官网地址:https://nacos.io/

Nacos源码地址:https://github.com/alibaba/nacos

进入https://github.com/alibaba/nacos/releases

直接选择对应下载包接口:

下载下来,然后解压,建议配置成咱们自己的数据库,比如MySQL数据库。在\conf目录下

application.properties配置文件中。

另外,一定要记得,创建数据库,在此数据库下执行脚本:nacos-mysql.sql

最后数据库中的表,有如下:

Linux/Unix/Mac 操作系统中使用下面命令启动Nacos(单机模式),找到Nacos的bin目录下:

代码语言:javascript
复制
sh startup.sh -m standalone

注意:必须安装有JVM,因为nacos是Java 开发的产品。

Windows 操作系统中,打开CMD,来到Nacos的bin目录下:

代码语言:javascript
复制
startup.cmd -m standalone

快速开始,请参官方文档,中文版请求地址:

https://nacos.io/zh-cn/docs/quick-start.html

项目启动后,我们直接访问:

http://localhost:8848/nacos/

如果需要输入用户名和密码,则世界输入nacos/nacos

这里有数据,是因为我的服务已经注册上去了。

这里的配置管理 表示 nacos作为配置中心的相关管理。服务管理 便是我们的服务注册信息管理,其他这里不做讨论。

本文中,nacos所处位置:

业务代码

本文的重点在于构建项目基础架构,所以,本文中不会展示过多的业务代码。

user-api

这个module主要是服务提供者和服务消费者共同使用的代码,通常包括:service接口、数据传输对象DTO、一些工具类。

我们定义一类service接口类:

代码语言:javascript
复制
public interface UserService {
    UserInfoDTO findUserInfoById(Long id);

    UserInfoDTO findUserInfo(String userName, String password);
}

一个数据传输对象(注意需要实现Serializable用作序列化):

代码语言:javascript
复制
public class UserInfoDTO implements Serializable {
    private Long id;
    private String userName;
    private Integer age;
    private Integer gender;
    private String phone;
    
    // 省略 get set
}

user-service

也叫user-provider,就这个意思,懂了就行,另外,在项目开发中,遵循项目开发命名规范来就行。这个module里才是我们真正的业务处理,还有就是数据库操作也基本上在这里面。

下面我把代码都贴一遍。

application.properties配置文件:

代码语言:javascript
复制
server.port=9002
spring.application.name=user-service

# dubbo 服务扫描基础包路径
dubbo.scan.base-packages=com.tian
dubbo.protocol.id=dubbo
# Dubbo 服务暴露的协议配置,其中子属性 name 为协议名称,port 为协议端口( -1 表示自增端口,从 20880 开始)
dubbo.protocol.name=dubbo
dubbo.protocol.port=28801

spring.cloud.nacos.discovery.server-addr=localhost:8848
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/user-center?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456

mybatis.mapper-locations=classpath:mapper/**/*.xml
mybatis.type-aliases-package=com.tian.entity
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

UserServiceApplication项目启动类:

代码语言:javascript
复制
@SpringBootApplication
@MapperScan("com.tian.mapper")
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

数据库表对应的实体类:

代码语言:javascript
复制
public class User {
    private Long id;
    private String userName;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    
    //省略 set get
    
}

mapper接口类和xml:

代码语言:javascript
复制
<?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.tian.mapper.UserMapper">
    <resultMap id="BaseResultMap" type="com.tian.entity.User">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <result column="user_name" property="userName" jdbcType="VARCHAR"/>
        <result column="password" property="password" jdbcType="VARCHAR"/>
        <result column="age" property="age" jdbcType="INTEGER"/>
        <result column="gender" property="gender" jdbcType="INTEGER"/>
        <result column="phone" property="phone" jdbcType="VARCHAR"/>
    </resultMap>

    <sql id="BaseSQL">
        id,user_name,age,gender,phone
    </sql>

    <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="long">
        select
        <include refid="BaseSQL"/>
        from t_user where id=#{id}
    </select>

    <select id="findUserInfo" resultMap="BaseResultMap">
        select
        <include refid="BaseSQL"/>
        from t_user where user_name =#{userName} and password=#{password}
    </select>
</mapper>
代码语言:javascript
复制
public interface UserMapper {

    User selectByPrimaryKey(Long uId);

    User findUserInfo(@Param("userName") String userName, @Param("password") String password);
}

业务具体实现类(注意:这里的Service注解是dubbo中,不是spring中的):

代码语言:javascript
复制
@Service(protocol = "dubbo")
public class UserServiceImpl implements UserService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Resource
    private UserMapper userMapper;

    @Override
    public UserInfoDTO findUserInfoById(Long id) {
        logger.info("通过id查询用户信息,id={}", id);
        User user = userMapper.selectByPrimaryKey(id);
        if (user == null) {
            logger.info("用户信息不存在,id={}", id);
            return null;
        }
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        try {
            BeanUtils.copyProperties(userInfoDTO, user);
        } catch (Exception ex) {
            logger.error("bean 转换失败", ex);
        }
        return userInfoDTO;
    }

    @Override
    public UserInfoDTO findUserInfo(String userName, String password) {
        User user = userMapper.findUserInfo(userName, password);
        if(user == null){
            return null;
        }
        UserInfoDTO userInfoDTO = new UserInfoDTO();
        try {
            BeanUtils.copyProperties(userInfoDTO, user);
        } catch (Exception ex) {
            logger.error("bean 转换失败", ex);
        }
        return userInfoDTO;
    }
}

user-web

为了演示nacos作为分布式配置,所以,这个项目中的配置文件有所不同。

bootstrap.properties配置文件:

代码语言:javascript
复制
spring.application.name=user-web

spring.cloud.nacos.config.server-addr=localhost:8848
spring.cloud.nacos.config.file-extension=properties

UserController类:

代码语言:javascript
复制
@RestController
@RequestMapping("/user")
@RefreshScope//只需要在需要动态读取配置的类上添加此注解就可以使用@Value注解获取配置项
public class UserController {

    @Resource
    private IUserInfoService userInfoService;

    /**
     * nacos 作为配置中心 验证
     */
    @Value("${config.test}")
    private String configName;

    @GetMapping("/info/{id}")
    public ResultData findUserInfoById(@PathVariable("id") Long id) {
        //输出我们在nacos配置中心配置的内容
        System.out.println(configName);
        return userInfoService.findUserInfoById(id);
    }

    @PostMapping(value = "/login")
    public ResultData login(@RequestParam("userName") String userName,
                            @RequestParam("password") String password) {
        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(password)) {
            return ResultData.fail(ResultCodeEnum.PARAM_EMPTY.getCode(), ResultCodeEnum.PARAM_EMPTY.getMsg());
        }
        return userInfoService.login(userName, password);
    }
}

在user-web中,我们通常也会定义一个service目录,可以做一些数据包装转换之类的。

代码语言:javascript
复制
public interface IUserInfoService {

    /**
     *  查询用户信息
     */
    ResultData findUserInfoById(Long id);

    /**
     *  用户登录
     */
    ResultData login(String userName, String password);
}

实现类(注意:@Reference这个注解是Dubbo中的,protocol指定协议):

代码语言:javascript
复制
@Service
public class UserInfoServiceImpl implements IUserInfoService {

    @Reference(protocol = "dubbo")
    private UserService userService;

    @Override
    public ResultData findUserInfoById(Long id) {
        UserInfoDTO userInfoDTO = userService.findUserInfoById(id);
        if (userInfoDTO == null) {
            return ResultData.fail(ResultCodeEnum.SYSTEM_ERROR.getCode(), ResultCodeEnum.SYSTEM_ERROR.getMsg());
        }
        return ResultData.success(userInfoDTO);
    }

    @Override
    public ResultData login(String userName, String password) {
        UserInfoDTO userInfoDTO =userService.findUserInfo(userName, password);
        if (userInfoDTO == null) {
            return ResultData.fail(ResultCodeEnum.LOGIN_FAILD.getCode(), ResultCodeEnum.LOGIN_FAILD.getMsg());
        }
        return ResultData.success(userInfoDTO);
    }
}

项目启动类:

代码语言:javascript
复制
@SpringBootApplication
public class WebApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
}

ResultData返回数据类:

代码语言:javascript
复制
public class ResultData<T> {

    private T data;
    private int code;
    private String msg;

    public static <T> ResultData<T> success(T data) {
        return new ResultData(data, ResultCodeEnum.LOGIN_SUCCESS.getCode(), ResultCodeEnum.LOGIN_SUCCESS.getMsg());
    }

    public static <T> ResultData<T> fail(int code, String errorMsg) {
        return new ResultData(null, code, errorMsg);
    }
}

ResultCodeEnum返回码类:

代码语言:javascript
复制
public enum ResultCodeEnum {
    SUCCESS(200, "操作成功"),
    SYSTEM_ERROR(500, "系统错误"),
    PARAM_EMPTY(400, "参数为空"),
    LOGIN_SUCCESS(200, "登录成功"),
    LOGIN_FAILD(500, "登录失败");

    private int code;
    private String msg;
    //省略 相关非核心代码
}

好了,以上就是构建一个用户中心的主要代码,大家也可以在此基础之上,进行添加一些功能。同时还可以添加请求和相应参数的打印,也可以做一个统一异常处理。

后记

通过文中的方法,我们同样可以构建商品中心、订单中心,这样不就可以简单的构建一个电商项目了么?

好了,今天就分享到这里~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java后端技术全栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建项目结构
  • 添加maven依赖
  • Nacos 安装
  • 业务代码
    • user-api
      • user-service
        • user-web
        • 后记
        相关产品与服务
        对象存储
        对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档