本文介绍在不使用spring的情况下,javaweb整合dubbo的示例。
完整代码:https://github.com/saysky/saysky-dubbo-study-example/tree/master/dubbo-javaweb-example
代码结构如下
下面主要贴一些核心代码,完整代码见github,里面包括javaweb、spring和springboot整合dubbo
一、生产者 API 和 Impl
先看下生产者api模块和生产者代码实现的代码结构
1、User类
package com.liuyanzhao.provider.api.entity;
import java.io.Serializable;
/**
* 用户实体类,用于演示
* @author 言曌
* @date 2021/8/29 11:23 上午
*/
public class User implements Serializable {
private Integer id;
private String name;
private String sex;
public User() {
}
public User(Integer id, String name, String sex) {
this.id = id;
this.name = name;
this.sex = sex;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
2、UserService
package com.liuyanzhao.provider.api.service;
import com.liuyanzhao.provider.api.entity.User;
import java.sql.SQLException;
import java.util.List;
/**
* 用户服务接口
*
* @author 言曌
* @date 2021/8/29 11:24 上午
*/
public interface UserService {
/**
* 查询所有用户
*
* @return
*/
List<User> findAll() throws Exception;
/**
* 根据id查询
*
* @return
*/
User findById(Integer id) throws Exception;
}
3、UserServiceImpl
package com.liuyanzhao.provider.impl.service;
import com.liuyanzhao.provider.impl.dao.UserDao;
import com.liuyanzhao.provider.api.entity.User;
import com.liuyanzhao.provider.api.service.UserService;
import java.util.List;
/**
* 用户服务实现
*
* @author 言曌
* @date 2021/8/29 11:43 上午
*/
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDao();
@Override
public List<User> findAll() throws Exception {
return userDao.findAll();
}
@Override
public User findById(Integer id) throws Exception {
return userDao.findById(id);
}
}
4、UserDao
package com.liuyanzhao.provider.impl.dao;
import com.liuyanzhao.consumer.impl.util.DBUtil;
import com.liuyanzhao.provider.api.entity.User;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* 用户数据访问层,模拟从数据库取数据
*
* @author 言曌
* @date 2021/8/29 11:26 上午
*/
public class UserDao {
/**
* 获取所有用户
*
* @return
*/
public List<User> findAll() throws SQLException {
List<User> userList = new ArrayList<User>();
DBUtil dbUtil = new DBUtil();
ResultSet resultSet = dbUtil.query("SELECT * FROM user");
while (resultSet.next()) {
Integer id = resultSet.getInt("id");
String name = resultSet.getString("name");
String sex = resultSet.getString("sex");
userList.add(new User(id, name, sex));
}
return userList;
}
/**
* 根据用户id查询用户
*
* @return
*/
public User findById(Integer id) throws SQLException {
DBUtil dbUtil = new DBUtil();
ResultSet resultSet = dbUtil.query("SELECT * FROM user where id = " + id);
while (resultSet.next()) {
String name = resultSet.getString("name");
String sex = resultSet.getString("sex");
return new User(id, name, sex);
}
return null;
}
}
5、DBUtil
package com.liuyanzhao.provider.impl.util;
import java.sql.*;
/**
* 数据库查询工具类 for MySQL
*
* @author 言曌
* @date 2021/8/29 11:34 上午
*/
public class DBUtil {
private Connection conn;
private Statement stmt;
private ResultSet rs;
private final String DRIVER = "com.mysql.cj.jdbc.Driver";
private final String URL = "jdbc:mysql://127.0.0.1:3306/dubbo_study_example?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC";
private final String USERNAME = "root";
private final String PASSWWORD = "123456";
/**
* 获得数据库连接
*
* @return
*/
private boolean getConnection() {
try {
Class.forName(DRIVER);
conn = DriverManager.getConnection(URL, USERNAME, PASSWWORD);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 执行SQL
*
* @param sql
* @return
*/
public ResultSet query(String sql) {
if (getConnection()) {
try {
stmt = (Statement) conn.createStatement();
rs = stmt.executeQuery(sql);
return rs;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
} else {
return null;
}
}
/**
* 执行更新SQL
*
* @param sql
* @return
*/
public int update(String sql) {
if (getConnection()) {
try {
stmt = conn.createStatement();
int flag = stmt.executeUpdate(sql);
return flag;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
} else {
return -1;
}
}
/**
* 关闭连接
*
* @return
*/
public boolean closeAll() {
try {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
用户表
关于pom.xml这里就不贴了,impl 需要引入 api
二、生产者 Dubbo 整合,服务注册
代码结构如下
1、pom.xml
<?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>dubbo-javaweb-demo</artifactId>
<groupId>com.liuyanzhao</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>6</source>
<target>6</target>
</configuration>
</plugin>
</plugins>
</build>
<artifactId>dubbo-javaweb-example-provider-web</artifactId>
<dependencies>
<!-- impl里面包含了api-->
<dependency>
<groupId>com.liuyanzhao</groupId>
<artifactId>dubbo-javaweb-example-provider-impl</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<scope>provided</scope>
</dependency>
<!-- log4j日志-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!-- json转换,用于web模块-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.72</version>
</dependency>
<!-- 整合dubbo和nacos -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.8</version>
<!-- 原生API不引用spring-->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
</project>
2、web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<listener>
<listener-class>com.liuyanzhao.listener.DubboProviderListener</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<servlet>
<servlet-name>ProviderServlet</servlet-name>
<servlet-class>com.liuyanzhao.servlet.ProviderServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ProviderServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3、DubboProviderListener
主要作用是项目启动时调用,将我们的 UserService 和 RoleService 作为 dubbo 服务注册到 Nacos 中
package com.liuyanzhao.listener;
import com.liuyanzhao.consumer.impl.service.RoleServiceImpl;
import com.liuyanzhao.consumer.impl.service.UserServiceImpl;
import com.liuyanzhao.provider.api.service.RoleService;
import com.liuyanzhao.provider.api.service.UserService;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @author 言曌
* @date 2021/8/29 1:42 下午
*/
public class DubboProviderListener implements ServletContextListener {
/**
* 项目启动时加载
*
* @param sce
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
// 定义服务
ServiceConfig<UserServiceImpl> userService = new ServiceConfig<UserServiceImpl>();
userService.setInterface(UserService.class);
userService.setRef(new UserServiceImpl());
userService.setGroup("provider");
userService.setId(UUID.randomUUID().toString());
ServiceConfig<RoleServiceImpl> roleService = new ServiceConfig<RoleServiceImpl>();
roleService.setInterface(RoleService.class);
roleService.setRef(new RoleServiceImpl());
roleService.setGroup("provider");
roleService.setId(UUID.randomUUID().toString());
List<ServiceConfig> services = new ArrayList<ServiceConfig>();
services.add(roleService);
services.add(userService);
DubboBootstrap bootstrap = DubboBootstrap.getInstance();
// 设置应用名
bootstrap.application(new ApplicationConfig("provider-demo"))
// 设置注册中心
.registry(new RegistryConfig("nacos://127.0.0.1:8848"))
// 设置需要注册的服务
.services(services).start();
System.out.println("========> provider finish register services");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
4、配置tomcat启动项目
5、然后查看 nacos ,可以看到2个服务
三、消费者
消费者这里主要是调用一下生产者的2个服务,代码会简单点
代码结构如下
1、pom.xml
<?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>dubbo-javaweb-demo</artifactId>
<groupId>com.liuyanzhao</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<artifactId>dubbo-javaweb-example-consumer</artifactId>
<dependencies>
<!-- servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<scope>provided</scope>
</dependency>
<!-- 生产者api-->
<dependency>
<groupId>com.liuyanzhao</groupId>
<artifactId>dubbo-javaweb-example-provider-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- dubbo和nacos-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.8</version>
<!-- 原生API不引用spring-->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
</project>
2、web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<listener>
<listener-class>com.liuyanzhao.listener.DubboConsumerListener</listener-class>
</listener>
<servlet>
<servlet-name>ConsumerServlet</servlet-name>
<servlet-class>com.liuyanzhao.servlet.ConsumerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ConsumerServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3、DubboConsumerListener
项目启动时调用,设置需要发现的服务
package com.liuyanzhao.listener;
import com.liuyanzhao.provider.api.service.RoleService;
import com.liuyanzhao.provider.api.service.UserService;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.ArrayList;
import java.util.List;
/**
* 消费者发现服务
*
* @author 言曌
* @date 2021/8/29 1:42 下午
*/
public class DubboConsumerListener implements ServletContextListener {
/**
* 项目启动时加载
*
* @param sce
*/
public void contextInitialized(ServletContextEvent sce) {
// 定义reference
ReferenceConfig<UserService> userReference = new ReferenceConfig();
userReference.setInterface(UserService.class);
userReference.setGroup("provider");
ReferenceConfig<RoleService> roleReference = new ReferenceConfig();
roleReference.setInterface(RoleService.class);
roleReference.setGroup("provider");
List<ReferenceConfig> references = new ArrayList<ReferenceConfig>();
references.add(userReference);
references.add(roleReference);
DubboBootstrap bootstrap = DubboBootstrap.getInstance();
// 设置应用名
bootstrap.application(new ApplicationConfig("consumer-demo"))
// 设置注册中心
.registry(new RegistryConfig("nacos://127.0.0.1:8848"))
// 设置需要引用的dubbo服务
.references(references).start();
System.out.println("========> consumer finish discover services");
}
public void contextDestroyed(ServletContextEvent sce) {
}
}
4、ConsumerServlet
测试Servlet,用来判断是否能调用UserService和RoleService
package com.liuyanzhao.servlet;
import com.alibaba.fastjson.JSON;
import com.liuyanzhao.provider.api.entity.Role;
import com.liuyanzhao.provider.api.entity.User;
import com.liuyanzhao.provider.api.service.RoleService;
import com.liuyanzhao.provider.api.service.UserService;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.utils.ReferenceConfigCache;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* ConsumerServlet
*
* @author 言曌
* @date 2021/8/29 11:06 上午
*/
public class ConsumerServlet extends HttpServlet {
/**
* 响应一句话
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
StringBuilder content = new StringBuilder("dubbo-javaweb-example-consumer:\n");
resp.setContentType("application/json;charset=UTF-8");
// 调用 UserService
try {
ReferenceConfig<UserService> userReference = new ReferenceConfig();
userReference.setInterface(UserService.class);
userReference.setGroup("provider");
UserService userService = ReferenceConfigCache.getCache().get(userReference);
List<User> userList = userService.findAll();
content.append(JSON.toJSONString(userList)).append("\n");
} catch (Exception e) {
e.printStackTrace();
resp.getWriter().write("userService连接失败\n" + e.getMessage() + "\n");
}
// 调用 RoleService
try {
ReferenceConfig<RoleService> roleReference = new ReferenceConfig();
roleReference.setInterface(RoleService.class);
roleReference.setGroup("provider");
RoleService roleService = ReferenceConfigCache.getCache().get(roleReference);
List<Role> roleList = roleService.findAll();
content.append(JSON.toJSONString(roleList)).append("\n");
} catch (Exception e) {
e.printStackTrace();
resp.getWriter().write("roleService连接失败\n" + e.getMessage() + "\n");
}
resp.getWriter().write(content.toString());
}
}
5、配置tomcat,查看浏览器看效果
成功调用
2021年11月09日 02:07:04
每天醒来,敲醒自己的不是钟声,而是梦想