• springboot多模块开发以及整合dubbozookeeper进行服务管理


      之前研究了springboot单工程的使用,参考git地址:https://github.com/qiao-zhi/springboot-ssm

      下面研究springboot多模块开发的过程。

    1.模块简介:

    springboot-ssm-soa:  父工程

    springboot-ssm-common:   公共类工程,包括工具类等(其实这一模块还可以再分)
    springboot-ssm-bean     实体类工程
    springboot-ssm-service     服务层接口(不包括实现)
    springboot-ssm-dao          dao层接口与实现
    springboot-ssm-service-provider    服务层实现
    springboot-ssm-web    控制层与页面以及静态资源

     2.模块详细介绍

     2.1  springboot-ssm-soa 父工程

     pom文件:定义公用的jar包以及引入相应模块

    <?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>cn.qlq</groupId>
        <artifactId>springboot-ssm-soa</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>pom</packaging>
        <modules>
            <module>springboot-ssm-common</module>
            <module>springboot-ssm-bean</module>
            <module>springboot-ssm-service</module>
            <module>springboot-ssm-dao</module>
            <module>springboot-ssm-service-provider</module>
            <module>springboot-ssm-web</module>
        </modules>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.2.RELEASE</version>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!--springboot单元测试 -->
            <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-devtools</artifactId>
            </dependency>
    
            <!-- spring-boot整合mybatis -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.1.1</version>
            </dependency>
            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.6</version>
            </dependency>
    
            <!-- 使用事务需要引入这个包 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
    
            <!-- 引入 spring aop 依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
    
            <!-- 引入 redis 依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
            <!--pagehelper插件 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper</artifactId>
                <version>5.1.2</version>
            </dependency>
    
            <!-- 引入 freemarker 模板依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-freemarker</artifactId>
            </dependency>
    
            <!-- 引入 thymeleaf 模板依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
    
            <!-- commons工具包 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.4</version>
            </dependency>
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.4</version>
            </dependency>
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>3.2</version>
            </dependency>
            <dependency>
                <groupId>commons-lang</groupId>
                <artifactId>commons-lang</artifactId>
                <version>2.6</version>
            </dependency>
            <!-- 阿里的fastjson用于手动转JSON -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.56</version>
            </dependency>
        </dependencies>
    
        <distributionManagement>
            <repository>
                <id>releases</id>
                <url>http://192.168.0.133:8081/repository/maven-releases/</url>
            </repository>
            <snapshotRepository>
                <id>snapshots</id>
                <url>http://192.168.0.133:8081/repository/maven-snapshots/</url>
            </snapshotRepository>
        </distributionManagement>
    
        <build>
            <!-- 配置了很多插件 -->
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.5.1</version>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>

       注意:多模块项目仅仅需要在启动类所在的模块添加打包插件即可!不要在父类添加打包插件,因为那样会导致全部子模块都使用spring-boot-maven-plugin的方式来打包(例如BOOT-INF/com/xxx/xx)。

    2.2  springboot-ssm-bean 子项目

       这个模块存放的是项目的实体类。

    pom文件如下:

    <?xml version="1.0"?>
    <project
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>cn.qlq</groupId>
            <artifactId>springboot-ssm-soa</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <groupId>cn.qlq</groupId>
        <artifactId>springboot-ssm-bean</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springboot-ssm-bean</name>
        <url>http://maven.apache.org</url>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <dependencies>
        </dependencies>
    </project>

    2.3  springboot-ssm-common 子项目

       存放系统的工具类以及一些其他配置信息,其实这一模块还可以再分。

    pom如下:

    <?xml version="1.0"?>
    <project
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>cn.qlq</groupId>
            <artifactId>springboot-ssm-soa</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <groupId>cn.qlq</groupId>
        <artifactId>springboot-ssm-common</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springboot-ssm-common</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>cn.qlq</groupId>
                <artifactId>springboot-ssm-bean</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </project>

    2.4  springboot-ssm-dao 子项目

       dao模块,用于写dao层接口和mapp的xml实现。

    pom如下:

    <?xml version="1.0"?>
    <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <groupId>cn.qlq</groupId>
        <artifactId>springboot-ssm-soa</artifactId>
        <version>0.0.1-SNAPSHOT</version>
      </parent>
      <groupId>cn.qlq</groupId>
      <artifactId>springboot-ssm-dao</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <name>springboot-ssm-dao</name>
      <url>http://maven.apache.org</url>
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
      <dependencies>
          <dependency>
              <groupId>cn.qlq</groupId>
              <artifactId>springboot-ssm-bean</artifactId>
              <version>0.0.1-SNAPSHOT</version>
          </dependency>
      </dependencies>
    </project>

    applications-dao.properties文件内容如下:

    ############################################################
    #
    # Mybatis settings
    #
    ############################################################
    #jiazai mybatis peizhiwenjian(**代表任意目录,*代表任意多个字符)
    mybatis.mapper-locations = classpath:mapper/**/*Mapper.xml
    mybatis.config-location = classpath:mybatis/SqlMapConfig.xml
    mybatis.type-aliases-package = cn.qlq.bean
    
    ############################################################
    #
    # datasource settings
    #
    ############################################################
    spring.datasource.driver-class-name= com.mysql.jdbc.Driver
    spring.datasource.url = jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
    spring.datasource.username = root
    spring.datasource.password = 123456

    2.5  springboot-ssm-service 子项目

       service层接口,不写实现,实现类单独抽取是为了发布dubbo服务。

    <?xml version="1.0"?>
    <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <groupId>cn.qlq</groupId>
        <artifactId>springboot-ssm-soa</artifactId>
        <version>0.0.1-SNAPSHOT</version>
      </parent>
      <groupId>cn.qlq</groupId>
      <artifactId>springboot-ssm-service</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <name>springboot-ssm-service</name>
      <url>http://maven.apache.org</url>
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
      <dependencies>
          <dependency>
              <groupId>cn.qlq</groupId>
              <artifactId>springboot-ssm-dao</artifactId>
              <version>0.0.1-SNAPSHOT</version>
          </dependency>
      </dependencies>
    </project>

    2.6  springboot-ssm-service-provider 子项目

       service接口实现。单独抽取是为了发布dubbo服务。

    <?xml version="1.0"?>
    <project
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>cn.qlq</groupId>
            <artifactId>springboot-ssm-soa</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <groupId>cn.qlq</groupId>
        <artifactId>springboot-ssm-service-provider</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springboot-ssm-service-provider</name>
        <url>http://maven.apache.org</url>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <dependencies>
            <dependency>
                <groupId>cn.qlq</groupId>
                <artifactId>springboot-ssm-service</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>cn.qlq</groupId>
                <artifactId>springboot-ssm-common</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </project>

    2.7  springboot-ssm-web 子项目

       controller层以及页面都在这一模块。

    pom文件:

      引入spring-boot-maven-plugin插件是为了打包、引入内嵌的tomcat是为了打包为jar包可以直接运行,并且pom文件中打包方式为jar包。

    <?xml version="1.0"?>
    <project
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>cn.qlq</groupId>
            <artifactId>springboot-ssm-soa</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <groupId>springboot-ssm-web</groupId>
        <artifactId>springboot-ssm-web</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>springboot-ssm-web</name>
        <url>http://maven.apache.org</url>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <dependencies>
            <dependency>
                <groupId>cn.qlq</groupId>
                <artifactId>springboot-ssm-service-provider</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
            <!-- 设置Tomcat打包的时候不打包下面配置 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <!-- <scope>provided</scope> -->
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>

    applications.properties

      spring.profiles.active=dao是为了引入dao模块的applications-dao.properties文件。

    ###引入多个properties文件配置
    spring.profiles.active=dao
    
    ############################################################
    #
    # 日志相关配置(默认集成的有slf4j,Logback等)
    #
    ############################################################
    #指定配置文件的位置,只能是xml或者groovy结尾
    #logging.config=classpath:logback.xml
    #默认的日志级别
    logging.level.root=INFO
    # mapper 接口所在的包设置为 debug
    logging.level.cn.qlq.mapper=DEBUG
    #生成日志文件的位置
    logging.file=G:/springboot.log
    #生成日志文件的目录,名称默认为spring.log
    #logging.path=e:/
    #指定日志的格式
    #logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %clr(%logger){cyan} %clr(%msg%n){green}
    #logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
    
    ############################################################
    #
    # Server 服务端相关配置
    #
    ############################################################
    # 配置api端口号
    server.port=8088
    # 配置context-path, 一般来说这个配置在正式发布的时候不配置
    server.context-path=/MySpringboot
    server.serverlet-path=*.do,*.action
    # 错误页,指定发生错误时,跳转的URL --> BasicErrorController
    #server.error.path=/error
    # session最大超时时间(分钟),默认为30分钟
    server.session-timeout=60
    # 该服务绑定IP地址,启动服务器时如本机不是该IP地址则抛出异常启动失败, 
    # 只有特殊需求的情况下才配置, 具体根据各自的业务来设置
    #server.address=192.168.1.2
    
    ############################################################
    # Server - tomcat 相关常用配置
    ############################################################
    # tomcat最大线程数, 默认为200
    #server.tomcat.max-threads=250
    # tomcat的URI编码
    server.tomcat.uri-encoding=UTF-8
    # 存放Tomcat的日志、Dump等文件的临时文件夹,默认为系统的tmp文件夹
    #(如:C:%usersShanhyAppDataLocalTemp)
    #server.tomcat.basedir=H:/springboot-tomcat-tmp
    # 打开Tomcat的Access日志,并可以设置日志格式的方法:
    #server.tomcat.access-log-enabled=true
    #server.tomcat.access-log-pattern=
    # accesslog目录,默认在basedir/logs
    #server.tomcat.accesslog.directory=
    # 日志文件目录
    #logging.path=H:/springboot-tomcat-tmp
    # 日志文件名称,默认为spring.log
    #logging.file=myapp.log
    
    
    ############################################################
    #
    # thymeleaf 静态资源配置
    #
    ############################################################
    spring.thymeleaf.prefix=classpath:/templates/thymeleaf/x-admin/
    spring.thymeleaf.suffix=.html
    spring.thymeleaf.mode=HTML5
    spring.thymeleaf.encoding=UTF-8
    spring.thymeleaf.content-type=text/html
    # 关闭缓存, 即时刷新, 上线生产环境需要改为true
    spring.thymeleaf.cache=false
    #关闭thymeleaf引擎
    #spring.thymeleaf.enabled=false
    
    
    spring.messages.basename=i18n/messages
    spring.messages.cache-seconds=3600
    spring.messages.encoding=UTF-8
    
    spring.jackson.date-format=yyyy-MM-dd
    spring.jackson.time-zone=GMT+8
    spring.jackson.serialization.write-dates-as-timestamps=false
    
    ############################################################
    #
    # REDIS 配置
    #
    ############################################################
    # Redis数据库索引(默认为0)
    spring.redis.database=1
    # Redis服务器地址
    spring.redis.host=localhost
    # Redis服务器连接端口
    spring.redis.port=6379
    # Redis服务器连接密码(默认为空)
    spring.redis.password=
    # 连接池最大连接数(使用负值表示没有限制)
    spring.redis.pool.max-active=1000
    # 连接池最大阻塞等待时间(使用负值表示没有限制)
    spring.redis.pool.max-wait=-1
    # 连接池中的最大空闲连接
    spring.redis.pool.max-idle=10
    # 连接池中的最小空闲连接
    spring.redis.pool.min-idle=2
    # 连接超时时间(毫秒)
    spring.redis.timeout=0

    MySpringBootApplication.java是运行类的入口:

    package cn.qlq;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    
    @SpringBootApplication
    @ServletComponentScan("cn") // Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。
    public class MySpringBootApplication {
        public static void main(String[] args) {
            // 入口运行类
            SpringApplication.run(MySpringBootApplication.class, args);
        }
    }

      其运行方式依然是点击上面主类运行即可。

      打包方式也是同普通的springboot项目,只不过打包方式选择在web层进行打包,所以web层的pom文件加入了spring-boot-maven-plugin插件与内置的tomcat。参考:https://www.cnblogs.com/qlqwjy/p/8548690.html

    注意:

      上面多个模块之间相互依赖,所以要先执行maven install上传到本地仓库,然后对本地仓库重新建立索引引入对应的jar包即可。而且父工程不可以引入spring-boot-maven-plugin插件,否则会影响打的jar包。(我们知道springboot打的jar包是其特有的目录结构,会加入其自身的一些类)

            

    git地址:https://github.com/qiao-zhi/springboot-ssm-soa

    原来没有分模块的项目地址:https://github.com/qiao-zhi/springboot-ssm

    项目需要的sql脚本也可以在没有分模块的git地址进行下载。

    ======对service的实现进行dubbo发布服务到zookeeper====

      上面已经对普通的springboot项目进行改造完成。在此基础上对springboot-ssm-service-provider模块进行改造,将服务发布到zookeeper中以及web层从dubbo消费服务。前期zookeeper的集群搭建以及启动zookeeper参考之前的zookeeper学习。

       只是在上面的基础上稍作修改。

    1.父工程pom.xml文件增加dubbo-spring-boot-starter以及zkclient依赖

            <!-- 引入dubbo-spring-boot-starter以及zkclient依赖 -->
            <dependency>
                <groupId>com.alibaba.spring.boot</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>2.0.0</version>
            </dependency>
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.9</version>
            </dependency>

     2.bean工程的所有class都是些Serializable接口

     3.commons工程基本不变

     4.dao工程也基本不变

     5.service工程的UserService增加下面方法

    public PageInfo<User> getPageInfoUsers(Map condition);

    6.springboot-ssm-service-provider模块修改如下

    1.引入applications.properties文件 --引入dubbo服务相关配置与引入dao层的properties配置文件

    ###引入多个properties文件配置
    spring.profiles.active=dao
    
    ############################################################
    #
    # DUBBO相关配置
    #
    ############################################################
    #当前服务/应用名称
    spring.dubbo.application.name=provider
    #注册中心的协议和地址
    spring.dubbo.server=true
    spring.dubbo.registry=zookeeper://127.0.0.1:2181
    #通信规则(通信协议和接口)
    spring.dubbo.protocol.name=dubbo
    spring.dubbo.protocol.port=20880

    2.UserServiceImpl修改为如下:

      通过@com.alibaba.dubbo.config.annotation.Service(version = "1.0.0")发布dubbo服务;实现getPageInfoUsers方法(支持pagehelper分页)

    package cn.qlq.service.impl.user;
    
    import java.util.List;
    import java.util.Map;
    
    import org.apache.commons.collections.MapUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.github.pagehelper.PageHelper;
    import com.github.pagehelper.PageInfo;
    
    import cn.qlq.bean.user.User;
    import cn.qlq.bean.user.UserExample;
    import cn.qlq.bean.user.UserExample.Criteria;
    import cn.qlq.mapper.user.UserMapper;
    import cn.qlq.service.user.UserService;
    
    @Service
    @com.alibaba.dubbo.config.annotation.Service(version = "1.0.0")
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserMapper userMapper;
    
        public List<User> findAllUser() {
            UserExample userExample = new UserExample();
            List<User> list = userMapper.selectByExample(userExample);
            return list;
        }
    
        @Override
        public void addUser(User user) {
            userMapper.insert(user);
        }
    
        @Override
        public List<User> getUsers(Map condition) {
            UserExample userExample = new UserExample();
            if (StringUtils.isNotBlank(MapUtils.getString(condition, "username"))) {
                Criteria createCriteria = userExample.createCriteria();
                createCriteria.andUsernameLike("%" + MapUtils.getString(condition, "username") + "%");
            }
            List<User> list = userMapper.selectByExample(userExample);
            return list;
        }
    
        @Override
        public void deleteUser(int id) {
            userMapper.deleteByPrimaryKey(id);
        }
    
        @Override
        public User getUser(int id) {
            return userMapper.selectByPrimaryKey(id);
        }
    
        @Override
        public void updateUser(User user) {
            userMapper.updateByPrimaryKeySelective(user);
        }
    
        @Override
        public PageInfo<User> getPageInfoUsers(Map condition) {
    
            PageHelper.startPage(MapUtils.getIntValue(condition, "pageNum"), MapUtils.getIntValue(condition, "pageSize"));
            UserExample userExample = new UserExample();
            if (StringUtils.isNotBlank(MapUtils.getString(condition, "username"))) {
                Criteria createCriteria = userExample.createCriteria();
                createCriteria.andUsernameLike("%" + MapUtils.getString(condition, "username") + "%");
            }
            List<User> list = userMapper.selectByExample(userExample);
    
            return new PageInfo<User>(list);
        }
    
    }

    3.编写DubboServiceProvider.java发布dubbo服务

    package cn.qlq.service.impl;
    
    import java.util.concurrent.CountDownLatch;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
    
    @SpringBootApplication
    @EnableDubboConfiguration
    @MapperScan("cn.qlq.mapper")
    public class DubboServiceProvider {
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch countDownLatch = new CountDownLatch(1);
            // 入口运行类
            SpringApplication.run(DubboServiceProvider.class, args);
    
            countDownLatch.await();
        }
    }

    7.  springboot-ssm-web如下修改

    以UserController为例子:

      @Reference(version = "1.0.0")是从zookeeper注册中心消费服务

    package cn.qlq.controller;
    
    import java.util.Date;
    import java.util.Map;
    
    import org.apache.commons.collections.MapUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.alibaba.dubbo.config.annotation.Reference;
    import com.github.pagehelper.PageInfo;
    
    import cn.qlq.annotation.MyLogAnnotation;
    import cn.qlq.bean.user.User;
    import cn.qlq.service.user.UserService;
    import cn.qlq.utils.JSONResultUtil;
    import cn.qlq.utils.ValidateCheck;
    
    @Controller /** 自动返回的是json格式数据 ***/
    @RequestMapping("user")
    public class UserController {
    
        private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    
        @Reference(version = "1.0.0")
        private UserService userService;
    
        /**
         * 添加user
         * 
         * @param user
         *            springMVC自动映射的实体
         * @return
         */
        @RequestMapping("addUser")
        @ResponseBody
        public JSONResultUtil addUser(User user) {
            user.setCreatetime(new Date());
            logger.info("user -> {}", user);
            userService.addUser(user);
            return JSONResultUtil.ok();
        }
    
        /**
         * 分页查询user
         * 
         * @param condition
         * @return
         */
        @RequestMapping("getUsers")
        // @Cacheable(value = "usersCache", keyGenerator = "keyGenerator") //
        // 在redis中开启key为findAllUser开头的存储空间。key和keyGenerator只能使用一个
        @MyLogAnnotation(operateDescription = "分页查询用户")
        @ResponseBody
        public PageInfo<User> getUsers(@RequestParam Map condition) {
            if (ValidateCheck.isNull(MapUtils.getString(condition, "pageNum"))) { // 如果不为空的话改变当前页号
                condition.put("pageNum", 1);
            }
            if (ValidateCheck.isNull(MapUtils.getString(condition, "pageSize"))) { // 如果不为空的话改变当前页大小
                condition.put("pageSize", 6);
            }
    
            PageInfo<User> pageInfo = userService.getPageInfoUsers(condition);
            return pageInfo;
        }
    
        /**
         * 删除user
         * 
         * @param user
         *            springMVC自动映射的实体
         * @return
         */
        @RequestMapping("deleteUser")
        @ResponseBody
        public JSONResultUtil deleteUser(int id) {
            userService.deleteUser(id);
            return JSONResultUtil.ok();
        }
    
        /**
         * 跳转打修改用户页面
         * 
         * @param id
         * @return
         */
        @RequestMapping("updateUser")
        public String updateUser(int id, ModelMap map) {
            User user = userService.getUser(id);
            map.addAttribute("user", user);
            return "updateUser";
        }
    
        /**
         * 添加user
         * 
         * @param user
         *            springMVC自动映射的实体
         * @return
         */
        @RequestMapping("doUpdateUser")
        @ResponseBody
        public JSONResultUtil doUpdateUser(User user) {
            logger.info("user -> {}", user);
            userService.updateUser(user);
            return JSONResultUtil.ok();
        }
    }

    pom.xml依赖于接口,不依赖实现类。

    <?xml version="1.0"?>
    <project
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>cn.qlq</groupId>
            <artifactId>springboot-ssm-soa</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <groupId>springboot-ssm-web</groupId>
        <artifactId>springboot-ssm-web</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>springboot-ssm-web</name>
        <url>http://maven.apache.org</url>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <dependencies>
            <!-- 设置Tomcat打包的时候不打包下面配置 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <!-- <scope>provided</scope> -->
            </dependency>
            <dependency>
                <groupId>cn.qlq</groupId>
                <artifactId>springboot-ssm-service</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>cn.qlq</groupId>
                <artifactId>springboot-ssm-common</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>

    8.测试:

    (1) 先启动springboot-ssm-service-provider模块的生产服务类DubboServiceProvider,启动后从dubbo-admin查看如下:

    (2)启动web模块进行访问之后查看消费者:

      至此基于dubbo服务的SOA搭建基本完成。

    下面总结自己在集成dubbo服务时遇到的坑。

    1.服务生产者类直接调用的时候报错找不到mapper,也就是没有扫描mapper包,因此在启动类头上增加注解如下:

    package cn.qlq.service.impl;
    
    import java.util.concurrent.CountDownLatch;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
    
    @SpringBootApplication
    @EnableDubboConfiguration
    @MapperScan("cn.qlq.mapper")
    public class DubboServiceProvider {
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch countDownLatch = new CountDownLatch(1);
            // 入口运行类
            SpringApplication.run(DubboServiceProvider.class, args);
    
            countDownLatch.await();
        }
    }

     2.dubbo服务整合pageHelper分页的时候原来是在controller进行分页,dubbo服务从注册中心获取之后分页无效,因此修改为将条件传到serivce层进行分页

    原来的controller:

        @RequestMapping("getUsers")
    //    @Cacheable(value = "usersCache", keyGenerator = "keyGenerator") // 在redis中开启key为findAllUser开头的存储空间。key和keyGenerator只能使用一个
        @MyLogAnnotation(operateDescription = "分页查询用户")
        @ResponseBody
        public PageInfo<User> getUsers(@RequestParam Map condition) {
            int pageNum = 1;
            if (ValidateCheck.isNotNull(MapUtils.getString(condition, "pageNum"))) { // 如果不为空的话改变当前页号
                pageNum = Integer.parseInt(MapUtils.getString(condition, "pageNum"));
            }
            int pageSize = DefaultValue.PAGE_SIZE;
            if (ValidateCheck.isNotNull(MapUtils.getString(condition, "pageSize"))) { // 如果不为空的话改变当前页大小
                pageSize = Integer.parseInt(MapUtils.getString(condition, "pageSize"));
            }
            // 开始分页
            PageHelper.startPage(pageNum, pageSize);
            List<User> users = new ArrayList<User>();
            try {
                users = userService.getUsers(condition);
            } catch (Exception e) {
                logger.error("getUsers error!", e);
            }
            PageInfo<User> pageInfo = new PageInfo<User>(users);
            return pageInfo;
        }

    原来的serviceImpl:

        @Override
        public List<User> getUsers(Map condition) {
            UserExample userExample = new UserExample();
            if (StringUtils.isNotBlank(MapUtils.getString(condition, "username"))) {
                Criteria createCriteria = userExample.createCriteria();
                createCriteria.andUsernameLike("%" + MapUtils.getString(condition, "username") + "%");
            }
            List<User> list = userMapper.selectByExample(userExample);
            return list;
        }

    整合dubbo服务的controller

        @RequestMapping("getUsers")
        // @Cacheable(value = "usersCache", keyGenerator = "keyGenerator") //
        // 在redis中开启key为findAllUser开头的存储空间。key和keyGenerator只能使用一个
        @MyLogAnnotation(operateDescription = "分页查询用户")
        @ResponseBody
        public PageInfo<User> getUsers(@RequestParam Map condition) {
            if (ValidateCheck.isNull(MapUtils.getString(condition, "pageNum"))) { // 如果不为空的话改变当前页号
                condition.put("pageNum", 1);
            }
            if (ValidateCheck.isNull(MapUtils.getString(condition, "pageSize"))) { // 如果不为空的话改变当前页大小
                condition.put("pageSize", 6);
            }
    
            PageInfo<User> pageInfo = userService.getPageInfoUsers(condition);
            return pageInfo;
        }

    整合dubbo的serviceImpl

        @Override
        public PageInfo<User> getPageInfoUsers(Map condition) {
    
            PageHelper.startPage(MapUtils.getIntValue(condition, "pageNum"), MapUtils.getIntValue(condition, "pageSize"));
            UserExample userExample = new UserExample();
            if (StringUtils.isNotBlank(MapUtils.getString(condition, "username"))) {
                Criteria createCriteria = userExample.createCriteria();
                createCriteria.andUsernameLike("%" + MapUtils.getString(condition, "username") + "%");
            }
            List<User> list = userMapper.selectByExample(userExample);
    
            return new PageInfo<User>(list);
        }
  • 相关阅读:
    C#库
    大话设计模式--简单工厂模式
    weka平台下手动造.arff的数据
    NIM博弈的必胜取法
    求一个全排列函数: 如p([1,2,3])输出:[123],[132],[213],[231],[312],[321]. 求一个组合函数 如p([1,2,3])输出:[1],[2],[3],[1,2],[2,3],[1,3],[1,2,3]
    哥德巴赫猜想
    C#格式化输出
    meta文件里指定资源
    chromatic aberration
    uber shader
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/10553052.html
Copyright © 2020-2023  润新知