SSM+Dubbo搭建生产者消费者系统(附源码)

1 篇文章 0 订阅
1 篇文章 0 订阅

前言

在网上找了好多教程,可是要不没有给出源码,要么是给的代码有问题,就很少看到有博主给出完整的、适合小白的SSM+Dubbo教程。刚好我自己折腾出来了,所以就出个小教程,给各位刚入门的小白指条明路。

源码可以看关联的下载链接

1、基本架构

我们的架构很简单,就是生产者+消费者,二者之间的通信靠ZooKeeper完成。

先来看张模块分布图

只需要三个模块:其中

  • myapi仅仅用来提供接口,打包方式为jar
  • provider提供Bean,打包方式为war
  • consumer是消费端,打包方式为war

接下来讲解如何完整地编写这个项目。

2、开启ZooKeeper

这一步非常简单,网上的教程到处都是,随便来个ZooKeeper都行

3、myapi

该模块为provider与consumer提供依赖,就一个接口和一个pojo,代码如下

package api;

import pojo.Role;

import java.util.List;

public interface IRoleService {
    Role selectRole(String id);

    void insertRole(Role role);

    List<Role> getList(String rolename);

}

以及

package pojo;

import java.io.Serializable;

public class Role implements Serializable {
    private String id;
    private String rolename;
    private String note;


    public Role() {
    }

    public Role(String id, String rolename, String note) {
        this.id = id;
        this.rolename = rolename;
        this.note = note;
    }

    public String getId() {
        return id;
    }

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

    public String getRolename() {
        return rolename;
    }

    public void setRolename(String rolename) {
        this.rolename = rolename;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

}

这部分还是很简单的,不详细叙述了

4、provider

这部分就有点意思了,先看看结构

我已经尽可能简化了,没必要的文件都给删掉了。如果各位大佬有更好的优化方案,欢迎不吝赐教。

一边放代码一边讲需要注意的地方

1、RoleService

这是实现类,也是生产者主要负责生产的Bean。这里有两个值得注意的地方, 想少走弯路的话,还请注意一下这些细节:

  1. 注解@Service引用的是import org.springframework.stereotype.Service;而非Dubbo提供的那个@Service
  2. 该类实现了BeanNameAware, BeanFactoryAware, InitializingBean,主要目的是为了知道该类是否已经被加载成Bean了。如果启动日志中没有那些输出语句,那说明生产者端出了问题。
package service;

import api.IRoleService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
import pojo.Role;

import java.util.List;

@Service
public class RoleService implements IRoleService,
        BeanNameAware, BeanFactoryAware, InitializingBean {

    @Override
    public Role selectRole(String id) {
        Role role = new Role();
        role.setId("此时此刻");
        return role;

    }

    @Override
    public void insertRole(Role role) {
        System.out.println("执行了插入语句");
    }

    @Override
    public List<Role> getList(String rolename) {
        return null;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("Bean被初始化了!!!");
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("Bean被初始化了!!!");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Bean被初始化了!!!");
    }
}

2、provider-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="provider"/>
    <!-- 使用zookeeper注册中心暴露服务地址 即zookeeper的所在服务器ip地址和端口号 -->
    <!--如果是Windows本地的,那就是自己的ip-->
    <dubbo:registry address="zookeeper://192.168.1.103:2181" check="false"/>
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" host="192.168.1.103"/>
    <dubbo:consumer check="false"/>


    <!--引入rpc文件-->
    <import resource="classpath:dubbo/rpc.xml"/>
</beans>

3、rpc.xml

在这里注册生产者要生产的Bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">


    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="api.IRoleService" ref="roleService"/>

</beans>

4、applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation=
               "http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/tx
                http://www.springframework.org/schema/tx/spring-tx.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop.xsd
                http://www.springframework.org/schema/task
                http://www.springframework.org/schema/task/spring-task-3.2.xsd
                http://code.alibabatech.com/schema/dubbo
                http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!--使用注解驱动Spring IoC-->
    <context:annotation-config/>
    <!--把扫描到的资源Bean装载进Spring IoC-->
    <context:component-scan base-package="service"/>

    <import resource="dubbo/provider-config.xml"/>

</beans>

5、log4j.properties

log4j.rootLogger=DEBUG , stdout
log4j.logger.org.mybatis=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n

6、mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://www.mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--引入属性文件,用来配置数据库-->
    <!--<properties resource="jdbc.properties"/>-->
    <settings>
        <!--下面这些配置能让mapper.xml文件运行时打印sql语句-->
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <typeAliases>
        <!-- 别名 -->
        <!--<typeAlias type="com.pojo.Role" alias="role"/>-->
        <!--像下面这样写的话会出现匪夷所思的bug:com/microsoft/schemas/vml/STShadowType-->
        <!--所以必须精确到具体的类所在的包名-->
        <!--错误的写法-->
        <!--<package name="com"/>-->
        <package name="service"/>
    </typeAliases>
</configuration>

7、web.xml

有一个细节一定要注意!!!!

别忘了Spring IoC容器的启动语句!!!!

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>Archetype Created Web Application</display-name>
    <!-- log4j配置文件地址 -->
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>classpath:/log4j.properties</param-value>
    </context-param>

    <!-- Spring IoC配置文件地址,同时也是Spring AOP的配置地址. -->
    <!--  因为Spring IoC和Spring AOP都是Spring的组件,所以这个也可以看成Spring的配置地址-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/applicationContext.xml</param-value>
    </context-param>

    <!-- Log4j的监听器要放在spring监听器前面 -->
    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>

5、consumer

结构图如下

消费者端比较简单,只要生产者端OK了,这边也不太可能会出问题。

1、MyController

注意,一定要注意!!!

这里使用的注解是@Resource,而非@Autowired

package controller;

import api.IRoleService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import pojo.Role;

import javax.annotation.Resource;

@Controller("/myController")
@RequestMapping("/my")
public class MyController {

    @Resource
    private IRoleService roleService;

    @RequestMapping("/index")
    public ModelAndView index() {
        ModelAndView modelAndView = new ModelAndView();
        Role role = roleService.selectRole("111222");
        System.out.println(role.getId());
        modelAndView.setViewName("jsp/index.jsp");
        return modelAndView;
    }

}

2、consumer-config.xml

前面几行能够解决Dubbo端口冲突问题。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="consumer">
        <dubbo:parameter key="qos.enable" value="true"/>
        <dubbo:parameter key="qos.accept.foreign.ip" value="false"/>
        <dubbo:parameter key="qos.port" value="33333"/>
    </dubbo:application>


    <!--    没错,需要用push!-->

    <!--关闭注册中心启动时检查:(注册订阅失败时报错)-->
    <dubbo:registry address="zookeeper://192.168.1.103:2181" check="false"/>
    <dubbo:protocol host="192.168.1.103"/>
    <!--关闭所有服务的启动时检查:(没有提供者时报错)  写在定义服务消费者一方-->
    <dubbo:consumer check="false"/>


    <!--引入rpc文件-->
    <import resource="classpath:dubbo/rpc.xml"/>

</beans>

3、rpc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">


    <!--生成远程服务代理,可以像使用本地bean一样使用demoService-->
    <!-- 具体的实现bean -->
    <dubbo:reference interface="api.IRoleService" id="roleService"/>

</beans>

4、applicationContext.xml

有些配置的语句我感觉没啥用,但是我也懒得删,所以就写着了

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation=
               "http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/tx
                http://www.springframework.org/schema/tx/spring-tx.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop.xsd
                http://www.springframework.org/schema/task
                http://www.springframework.org/schema/task/spring-task-3.2.xsd
                http://code.alibabatech.com/schema/dubbo
                http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--开启切面-->
    <aop:aspectj-autoproxy/>
    <!--使用注解驱动Spring IoC-->
    <context:annotation-config/>
    <!--把扫描到的资源Bean装载进Spring IoC-->
    <!--这种写法居然也不会报错-->
    <context:component-scan base-package="controller"/>

    <!--注解驱动扫描task-->
    <task:annotation-driven/>


    <import resource="dubbo/consumer-config.xml"/>


</beans>

5、dispatcher-servlet.xml

<?xml version='1.0' encoding='UTF-8' ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
    <!-- 扫描所有的controller -->
    <!--指定一个package进行扫描.也可以配置com.*-->
    <!--这个扫描项在Spring IoC的配置中也有相同的一份,但是二者都必须保留-->
    <context:component-scan base-package="controller"/>


    <!-- 定义视图解析器 -->
    <!-- 找到Web工程/WEB-INF/JSP文件夹,且文件结尾为jsp的文件作为映射 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/" p:suffix=""/>
</beans>

6、mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://www.mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--引入属性文件,用来配置数据库-->
    <properties resource="jdbc.properties"/>
    <settings>
        <!--下面这些配置能让mapper.xml文件运行时打印sql语句-->
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <typeAliases>
        <!-- 别名 -->
        <!--<typeAlias type="com.pojo.Role" alias="role"/>-->
        <!--像下面这样写的话会出现匪夷所思的bug:com/microsoft/schemas/vml/STShadowType-->
        <!--所以必须精确到具体的类所在的包名-->
        <!--错误的写法-->
        <!--<package name="com"/>-->
        <package name="api"/>
        <package name="pojo"/>
    </typeAliases>
</configuration>

剩下的代码感觉没啥重要的了,那么只需要配置tomcat启动就可以了。

如果有什么不太明确的地方,欢迎去下载源码研究研究。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值