博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
玩转 SSH(七):使用 dubbo + zookeeper 实现服务模块化
阅读量:7025 次
发布时间:2019-06-28

本文共 32455 字,大约阅读时间需要 108 分钟。

一、创建 SSMVCAnnoDemo 项目

点击菜单,选择“File -> New Project” 创建新项目。选择使用 archetype 中的 maven-quickstart 模版创建。

输入对应的项目坐标GroupId 和 ArtifactId

之后在项目名称中填入项目名称,这里我填的 ProjectName 和上文的 ArtifactId 相同,都是 SuperDemo。

点击确定后,等待 Maven 帮我们构建好项目的目录结构。当控制台显示 BUILD SUCCESS 就表示初始化完成了。

完成初始化之后,我们分别创建 model、interface、provider、consumer 模块,它们的作用分别是:

model:存放 POJO 文件的模块

interface:存放接口文件的模块

provider:提供服务的模块

consumer:调用服务的模块

二、配置 model 模块

在 SuperDemo 模块的 pom.xml 文件添加 JUnit、Log4J 等公共依赖:

junit
junit
${junit.version}
provided
org.slf4j
slf4j-api
1.7.6
org.slf4j
slf4j-log4j12
1.7.6
net.sf.json-lib
json-lib
2.4
jdk15

修改后的 pom.xml 为:

4.0.0
com.chanshuyi.SuperDemo
SuperDemo
1.0-SNAPSHOT
interface
model
provider
consumer
pom
SuperDemo
http://maven.apache.org
UTF-8
3.8.1
junit
junit
${junit.version}
provided
org.slf4j
slf4j-api
1.7.6
org.slf4j
slf4j-log4j12
1.7.6
net.sf.json-lib
json-lib
2.4
jdk15
pom.xml

下载 (密码:c1dy),这是MyBatis 官方的 MyBatis Generator,我们使用它将数据库表转化成 model、mapper 以及 SqlProvider 文件。

下载文件解压放到 provider 模块的 resources 目录下。进入 resources/mbg 目录,双击运行 generate.bat,程序自动将配置文件 resources/mbgconfig.xml 中配置的表格映射成相对应的文件。

将上面生成后的 com.chanshuyi.model.User 类拷贝至 model 模块的 com.chanshuyi.model 包。

三、配置 interface 模块

打开 interface 模块的 pom.xml 模块,加入对于 SuperDemo 下 model 模块的依赖:

com.chanshuyi.SuperDemo
model
1.0-SNAPSHOT

创建 com.chanshuyi.dao.IUserDao 接口

package com.chanshuyi.dao;import com.chanshuyi.model.User;import java.util.List;import java.util.Map;/** * Created by chanshuyi on 2015/12/26. */public interface IUserDao {    User getUserById(int userId);    /**     *     * @param param Map中的key要与数据库表中的字段名相同     * @return     */    User getUserByMapSql(Map
param); List
getUserListByMapSql(Map
param);}

创建 com.chanshuyi.service.IUserService 接口

package com.chanshuyi.service;import com.chanshuyi.model.User;import java.util.List;import java.util.Map;/** * Created by chanshuyi on 2015/12/26. */public interface IUserService {    User getUserById(int userId);    /**     *     * @param param Map中的key要与数据库表中的字段名相同     * @return     */    User getUserByMapSql(Map
param); List
getUserListByMapSql(Map
param);}

四、配置 provider 模块

打开 provider 模块的 pom.xml 文件,加入全局属性声明

UTF-8
4.1.6.RELEASE
1.2

导入 Spring、MyBatis 等依赖

org.mybatis
mybatis
3.1.1
org.mybatis
mybatis-spring
1.1.1
org.springframework
spring-core
${springframework.version}
org.springframework
spring-tx
${springframework.version}
org.springframework
spring-orm
${springframework.version}
org.springframework
spring-jdbc
${springframework.version}
org.springframework
spring-web
${springframework.version}
org.springframework
spring-context
${springframework.version}
org.springframework
spring-beans
${springframework.version}
commons-logging
commons-logging
${commonsLogging.version}
org.aspectj
aspectjweaver
1.8.5
mysql
mysql-connector-java
5.1.21
com.alibaba
druid
1.0.6
com.alibaba
dubbo
2.5.3
org.springframework
spring
com.github.sgroschupf
zkclient
0.1
org.apache.zookeeper
zookeeper
3.3.3
com.sun.jmx
jmxri
com.sun.jdmk
jmxtools
javax.jms
jms
com.chanshuyi.SuperDemo
interface
1.0-SNAPSHOT

在 resources 目录下创建 applicationContext.xml

创建 MyBatis 配置文件 spring-mybatis.xml

1 
2
6 7
8
9 10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 66
67
68
69
70
71
72
73
74
75
76 77
78
79
80
81
82
83
84
85
86

配置 MyBatis 注解扫描路径,创建 mybatis-config.xml 配置文件:

创建数据库配置文件 jdbc.properties

############################  MySQL/Oracle/SQLServer Database Configuratioin Info ################################ MySQL Master DB Infojdbc.master.dialet=org.hibernate.dialect.MySQLDialectjdbc.master.driverClassName=com.mysql.jdbc.Driverjdbc.master.url=jdbc:mysql://127.0.0.1:3306/superdemojdbc.master.username=rootjdbc.master.password=sa# MySQL Slave DB Infojdbc.slave.dialet=org.hibernate.dialect.MySQLDialectjdbc.slave.driverClassName=com.mysql.jdbc.Driverjdbc.slave.url=jdbc:mysql://localhost:3306/superdemojdbc.slave.username=rootjdbc.slave.password=sa############################## Connection Pool Configuration Info ############################################### MySQL Master DB Settingjdbc.master.initialSize = 10jdbc.master.minIdle = 0jdbc.master.maxActive = 30# MySQL Slave DB Settingjdbc.slave.initialSize = 10jdbc.slave.minIdle = 0jdbc.slave.maxActive = 30

创建 resources/log4j.properties 文件,提供日志记录。

#Console Loglog4j.rootLogger=info, console, file# Write to Consolelog4j.appender.console=org.apache.log4j.ConsoleAppenderlog4j.appender.console.Threshold=INFOlog4j.appender.console.layout=org.apache.log4j.PatternLayoutlog4j.appender.console.layout.ConversionPattern=%5p %d{MM-dd HH:mm:ss}(%F:%L): %m%n# Write to Filelog4j.appender.file=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.file.File=${catalina.home}app/log/log.loglog4j.appender.file.layout=org.apache.log4j.PatternLayoutlog4j.appender.file.layout.ConversionPattern=%5p %d{MM-dd HH:mm:ss}(%F:%L): %m%n

在 com.chanshuyi.dao.mapper.UserMapper 类中增加 getUserListByMapSql 接口:

/** * 根据参数构造SQL进行查询 * @param param * @return */@SelectProvider(type = UserSqlProvider.class, method = "getUserListByMapSql")List
getUserListByMapSql(@Param("param") Map
param);

在 UserSqlProvider 类增加对上面接口 SQL 的实现:

/** * 获取查询SQL * @param param * @return */public String getUserListByMapSql(Map
param) { StringBuilder builder = new StringBuilder(); Map
realParam = (Map
)param.get("param"); //add select part builder.append(" select * from user where 1 = 1 "); //add condition part String conditionStr = ""; if(!StringUtil.isNullOrEmpty(realParam)){ conditionStr = getQueryCondition(realParam); if(!StringUtil.isNullOrEmpty(conditionStr)){ builder.append(conditionStr); } } return new String(builder);}public String getQueryCondition(Map
param){ StringBuilder builder = new StringBuilder(); //if param is null or empty, return empty String if(param == null || param.size() < 1){ return ""; } for(String key : param.keySet()){ String value = param.get(key); if(value != null && !value.isEmpty()){ builder.append(" and " + key + " = '" + value + "'"); } } return new String(builder);}

上面用到了 StringUtil.java,我们在 com.chanshuyi.util 中导入它:

package com.mszz.util;import java.util.Collection;import java.util.Map;/** * 字符串工具类 * @author chenxinquan * */public class StringUtil {    /**     * 判断对象或对象数组中每一个对象是否为空: 对象为null,字符序列长度为0,集合类、Map为empty     * @author zl     * @param obj     * @return     */    public static boolean isNullOrEmpty(Object obj) {        if (obj == null)            return true;        if (obj instanceof CharSequence)            return ((CharSequence) obj).length() == 0;        if (obj instanceof Collection)            return ((Collection) obj).isEmpty();        if (obj instanceof Map)            return ((Map) obj).isEmpty();        if (obj instanceof Object[]) {            Object[] object = (Object[]) obj;            if (object.length == 0) {                return true;            }            boolean empty = true;            for (int i = 0; i < object.length; i++) {                if (!isNullOrEmpty(object[i])) {                    empty = false;                    break;                }            }            return empty;        }        return false;    }}StringUtil.java
View Code

创建 com.chanshuyi.dao.impl.BaseDao.java 类,提供基本的数据库读写对象,并用注解方式将 SqlSession 注入。

package com.chanshuyi.dao.impl;import org.apache.ibatis.session.SqlSession;import org.springframework.beans.factory.annotation.Autowired;/** * 所有Service的基类,用来注入sqlSession */public class BaseDao {    /**     * 可写的sqlSession     */    @Autowired    protected SqlSession writableSQLSession;    /**     * 只读的sqlSession     */    @Autowired    protected SqlSession readonlySQLSession;}

创建 com.chanshuyi.dao.impl.UserDaoImpl.java 继承 BaseDao.java、实现 IUserDao 接口,并用 @Repository 创建名称为 userDao 的对象。

package com.chanshuyi.dao.impl;import com.chanshuyi.dao.IUserDao;import com.chanshuyi.dao.mapper.UserMapper;import com.chanshuyi.model.User;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.stereotype.Repository;import java.util.List;import java.util.Map;/** * Created by Administrator on 2015/12/26. */@Repository("userDao")public class UserDaoImpl extends BaseDao implements IUserDao {    private static Log logger = LogFactory.getLog(UserDaoImpl.class);    @Override    public User getUserById(int userId) {        UserMapper mapper = readonlySQLSession.getMapper(UserMapper.class);        return mapper.selectByPrimaryKey(userId);    }    /**     *     * @param param     * @return     */    @Override    public User getUserByMapSql(Map
param) { logger.info("getUserByMapSql 根据动态参数查询用户对象"); return getUserListByMapSql(param).size() > 0 ? getUserListByMapSql(param).get(0) : null; } /** * get**MapSql()类的方法只能用于各参数的等于查询 * 例如:select * from user where username = 1 and password = 3 (正确) * select * from user where username in (1,2,3) (错误,无法实现) * @param param * @return */ @Override public List
getUserListByMapSql(Map
param) { logger.info("getUserListByMapSql 根据动态参数查询用户对象列表"); UserMapper mapper = readonlySQLSession.getMapper(UserMapper.class); return mapper.getUserListByMapSql(param); }}

创建 com.chanshuyi.service.impl.UserServiceImpl 类,并添加 @Service 注解创建名称为 userService 的对象,并将 userDao 对象注入。

package com.chanshuyi.service.impl;import com.chanshuyi.dao.IUserDao;import com.chanshuyi.model.User;import com.chanshuyi.service.IUserService;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;import java.util.Map;/** * Created by Administrator on 2015/6/18. */@Service("userService")public class UserServiceImpl implements IUserService {    private static Log logger = LogFactory.getLog(UserServiceImpl.class);    @Autowired    IUserDao userDao;    @Override    public User getUserById(int userId) {        return userDao.getUserById(userId);    }    @Override    public User getUserByMapSql(Map
param) { return userDao.getUserByMapSql(param); } @Override public List
getUserListByMapSql(Map
param) { return userDao.getUserListByMapSql(param); }}

DAO 和 SERVICE 层的配置写好之后,需要在 applicationContext.xml 文件中配置扫描路径:

到这里基本 provider 大部分配置已经结束,下面我们需要启动 provider 模块,让它对外提供服务。

创建 com.chanshuyi.util.SystemDetails 类,用来打印系统的基本信息:

package com.chanshuyi.util;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.TimeZone;public class SystemDetails {    /**     * 输出系统基本信息     */    public static void outputDetails() {        timeZone();        currentTime();        os();    }    /**     * 输出系统时区     */    private static void timeZone() {        Calendar cal = Calendar.getInstance();        TimeZone timeZone = cal.getTimeZone();        System.out.println("系统时区:" + timeZone.getDisplayName());    }    /**     * 输出系统时间     */    private static void currentTime() {        String fromFormat = "yyyy-MM-dd HH:mm:ss";        SimpleDateFormat format = new SimpleDateFormat(fromFormat);        Date myDate = new Date();        System.out.println("系统时间:" + format.format(myDate));    }    /**     * 输出系统基本配置     */    private static void os() {        String osName = System.getProperty("os.name"); //操作系统名称        System.out.println("当前系统:" + osName);        String osArch = System.getProperty("os.arch"); //操作系统构架        System.out.println("当前系统架构" + osArch);        String osVersion = System.getProperty("os.version"); //操作系统版本        System.out.println("当前系统版本:" + osVersion);    }}

创建 com.chanshuyi.util.BeanFactoryUtil,用于加载 Spring 配置文件:

package com.chanshuyi.util;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanFactoryUtil {    private static ApplicationContext ctx_producer = null;    public final static String ApplicationContextRoot = "";    public final static String ApplicationContextPath = ApplicationContextRoot + "applicationContext.xml";    public static void init() {        if (ctx_producer == null) {            synchronized (BeanFactoryUtil.class) {                if(ctx_producer == null){                    String[] configLocations = new String[]{ApplicationContextPath};                    ctx_producer = new ClassPathXmlApplicationContext(configLocations);                }            }        }    }    public static ApplicationContext getContext() {        if (ctx_producer == null) {            init();        }        return ctx_producer;    }}

创建 com.chanshuyi.Launcher 类,用于启动 provider 服务,加载 Spring 配置文件,对外提供服务:

package com.chanshuyi;import com.chanshuyi.util.BeanFactoryUtil;import com.chanshuyi.util.SystemDetails;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;public class Launcher {    private static Log logger = LogFactory.getLog(Launcher.class);    /**     * @param args     */    public static void main(String[] args) {        System.out.println("=======================");        System.out.println("        Core包启动          ");        SystemDetails.outputDetails();        System.out.println("=======================");        getLocalip();        // 初始化spring        logger.info("开始初始化core服务");        BeanFactoryUtil.init();        try{            System.in.read();        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 取得本机ip地址 注意:Spring RmiServiceExporter取得本机ip的方法:InetAddress.getLocalHost()     */    private static void getLocalip() {        try {            System.out.println("服务暴露的ip: "                    + java.net.InetAddress.getLocalHost().getHostAddress());        } catch (Exception e) {            System.out.println(e.getMessage());        }    }}

我们还要创建一个 spring-provider.xml 文件,告诉 dubbo 我们的基本信息以及对外提供的服务:

记得在 applicationContext.xml 文件中将 spring-provider.xml 文件导入进去:

五、配置 consumer 模块

打开 pom.xml 文件,导入全局配置变量以及所需的 SpringMVC、Dubbo、Zookeeper、com.chanshuyi.SuperDemo.interface 依赖:

UTF-8
4.1.6.RELEASE
1.2
org.springframework
spring-webmvc
${springframework.version}
org.springframework
spring-core
${springframework.version}
org.springframework
spring-tx
${springframework.version}
org.springframework
spring-orm
${springframework.version}
org.springframework
spring-jdbc
${springframework.version}
org.springframework
spring-web
${springframework.version}
org.springframework
spring-context
${springframework.version}
org.springframework
spring-beans
${springframework.version}
commons-logging
commons-logging
${commonsLogging.version}
org.aspectj
aspectjweaver
1.8.5
com.alibaba
dubbo
2.5.3
org.springframework
spring
org.apache.zookeeper
zookeeper
3.3.3
com.sun.jmx
jmxri
com.sun.jdmk
jmxtools
javax.jms
jms
com.github.sgroschupf
zkclient
0.1
com.chanshuyi.SuperDemo
interface
1.0-SNAPSHOT

之后导入 Tomcat 启动插件,我们将通过 Maven 方式启动 Tomcat,这样就不必在本地配置一个 Tomcat 服务器。

org.apache.tomcat.maven
tomcat7-maven-plugin
2.1
5050
/
UTF-8
mgr
tomcat7

配置完成后的 pom.xml 文件是这样的:

SuperDemo
com.chanshuyi.SuperDemo
1.0-SNAPSHOT
4.0.0
com.chanshuyi.SuperDemo
app
war
app Maven Webapp
http://maven.apache.org
UTF-8
4.1.6.RELEASE
1.2
org.springframework
spring-webmvc
${springframework.version}
org.springframework
spring-core
${springframework.version}
org.springframework
spring-tx
${springframework.version}
org.springframework
spring-orm
${springframework.version}
org.springframework
spring-jdbc
${springframework.version}
org.springframework
spring-web
${springframework.version}
org.springframework
spring-context
${springframework.version}
org.springframework
spring-beans
${springframework.version}
commons-logging
commons-logging
${commonsLogging.version}
org.aspectj
aspectjweaver
1.8.5
com.alibaba
dubbo
2.5.3
org.springframework
spring
org.apache.zookeeper
zookeeper
3.3.3
com.sun.jmx
jmxri
com.sun.jdmk
jmxtools
javax.jms
jms
com.github.sgroschupf
zkclient
0.1
com.chanshuyi.SuperDemo
interface
1.0-SNAPSHOT
consumer
org.apache.tomcat.maven
tomcat7-maven-plugin
2.1
5050
/
UTF-8
mgr
tomcat7
View Code

之后在 main 目录下创建 java 目录,并设置为 Java Source(源码目录):

之后创建 com.chanshuyi.controller.UserController 类:

package com.chanshuyi.controller;import com.chanshuyi.service.IUserService;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import javax.servlet.http.HttpServletRequest;import java.util.HashMap;import java.util.Map;/** * Created by Administrator on 2015/6/18. */@Controller("userAction")@RequestMapping(value="/login")public class UserController{    private static Logger logger = LoggerFactory.getLogger(UserController.class);    private String message;    private String username;    private String password;    @Autowired    private IUserService userService;    @Autowired    private HttpServletRequest request;    @RequestMapping("")    public String login(@RequestParam(value = "username", required = false) String username,            @RequestParam(value = "password", required = false) String password){        try{            Map
param = new HashMap
(); param.put("username", username); param.put("password", password); if(userService.getUserByMapSql(param) != null){ message = "登录成功!"; logger.info(message); }else{ message = "登录失败!"; logger.info(message); } }catch(Exception e){ logger.warn(e.getMessage()); e.printStackTrace(); } request.setAttribute("message", message); return "index"; // 转到webapp/index.jsp页面 } /******** set/get ********/ public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}

创建 dubbo 配置文件 spring-consumer.xml,这个文件告诉 dubbo 本模块的基本信息以及请求的服务:

别忘了在 applicationContext.xml 中将 spring-consumer.xml 加入进去

创建 webapp/index.jsp 文件

<%@page language="java" pageEncoding="UTF-8"%><%@ page contentType="text/html;charset=utf-8" %><%@ page isELIgnored="false"%>    

Hello World!

<%-- 通过Struts传递参数,数据传递方式必须选择post,否则编码错误! --%>

${message}

Username:
Password:

修改 web.xml 文件,加载 SpringMVC 处理器

Archetype Created Web Application
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
encodingFilter
/*
spring
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:/spring-servlet.xml
1
spring
/

创建 SprngMVC 配置文件 spring-servlet.xml 

配置好之后将整个项目编译一次,为整个项目配置 Maven 命令:

六、启动 provider 模块和 consumer 模块测试

启动 provider 模块

先启动 zookeeper,再打开 Launcher.java 运行 main() 方法就可以了。看看控制台和 zookeeper 输出,如果没有报错,那就是启动成功了。

启动 consumer 模块

为 consumer 模块配置 Maven 启动命令:"tomcat7:run"

点击启动项目

测试联通

打开浏览器输入: 

输入 admin/password,点击 Login 按钮

提示登录成功,说明项目已经成功部署好。

 

链接: 密码:vutw

转载于:https://www.cnblogs.com/chanshuyi/p/5177939.html

你可能感兴趣的文章
JQuery选择器
查看>>
nmcli 使用记录---fatt
查看>>
【技巧】EasyUI分页组件pagination显示项控制
查看>>
POJ 3989 A hard Aoshu Problem
查看>>
ubuntu系统的谷歌浏览器的安装
查看>>
在JavaScript中"+"什么时候是链接符号,什么时候是加法运算?
查看>>
POJ1179 Polygon
查看>>
矩阵覆盖,基本DP题目
查看>>
定义一个不能被继承的类
查看>>
xgboost参数调优的几个地方
查看>>
python3编写网络爬虫13-Ajax数据爬取
查看>>
JVM监控启动参数
查看>>
npm 是干什么的
查看>>
视达配色教程1 色彩是什么
查看>>
枚举2--熄灯问题
查看>>
overload和override二者之间的区别
查看>>
Spring MVC工作原理(好用版)
查看>>
html5--1.18 div元素与布局
查看>>
HTML.7表单
查看>>
企业架构研究总结(7)——联邦企业架构之FEAF的出现和构成(下)
查看>>