天天看點

超詳細springboot整合dubbo

記錄一次

springboot

整合

dubbo

的過程,本文代碼 github 位址

https://github.com/liaozq0426/springboot-dubbo.git

文章目錄

    • 項目結構說明
    • 編寫父項目
    • 編寫服務接口子產品
    • 編寫服務提供者子產品
    • 編寫消費者子產品
    • 測試

項目結構說明

項目結構如下圖所示

超詳細springboot整合dubbo

springboot-dubbo

是一個maven的多子產品項目,各個子產品的作用如下

  1. springboot-dubbo-service

    子產品為

    dubbo

    服務接口項目,之是以将接口單獨建立一個項目,是因為

    dubbo

    接口既需要被

    dubbo

    服務實作類實作,也需要被消費者引用,也就是說

    dubbo

    接口項目會被多個項目使用。
  2. springboot-dubbo-service-impl

    子產品為

    dubbo

    服務的實作,它所有的

    service實作類

    都實作了

    springboot-dubbo-service

    中的接口
  3. springboot-dubbo-customer

    子產品為消費者項目,在實際開發中,

    dubbo

    往往會采用分布式的方式部署,即服務提供者和消費者部署在不同的伺服器,消費者還可能有多個,以實作負載均衡。

編寫父項目

建立一個

simple

類型的

maven

項目,勾選下圖紅色框中的選項,點選

next

超詳細springboot整合dubbo

填寫maven項目資訊,如下圖

超詳細springboot整合dubbo

其中要注意的的是,打包類型需要選擇

pom

,因為父項目中不需要寫任何邏輯代碼。填寫好後點選

Finish

按鈕即可。

父項目隻需要保留

pom.xml

檔案,其餘内容全部删除,

pom.xml

所需依賴如下

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.3.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring-boot-starter-parent.version>2.1.3.RELEASE</spring-boot-starter-parent.version>
		<mybatis-spring-boot-starter.version>1.3.2</mybatis-spring-boot-starter.version>
		<spring-boot-starter-log4j.version>1.3.8.RELEASE</spring-boot-starter-log4j.version>
		<druid-spring-boot-starter.version>1.1.10</druid-spring-boot-starter.version>
		<xstream.version>1.4.9</xstream.version>
		<commons-beanutils.version>1.9.3</commons-beanutils.version>
		<dubbo-spring-boot-starter.version>2.0.0</dubbo-spring-boot-starter.version>
		<dubbo.version>2.6.2</dubbo.version>
		<javassist.version>3.20.0-GA</javassist.version>
		<curator-framework.version>4.0.1</curator-framework.version>
		<curator-recipes.version>4.0.1</curator-recipes.version>
		<fastjson.version>1.2.48</fastjson.version>
		<commons-pool2.version>2.6.1</commons-pool2.version>
		<zookeeper.version>3.5.0-alpha</zookeeper.version>
		<javax.servlet-api.version>4.0.1</javax.servlet-api.version>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-starter-web</artifactId>
				<version>${spring-boot-starter-parent.version}</version>
			</dependency>
			<dependency>
				<groupId>org.mybatis.spring.boot</groupId>
				<artifactId>mybatis-spring-boot-starter</artifactId>
				<version>${mybatis-spring-boot-starter.version}</version>
			</dependency>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-starter-log4j</artifactId>
				<version>${spring-boot-starter-log4j.version}</version>
			</dependency>
			<dependency>
				<groupId>com.alibaba</groupId>
				<artifactId>druid-spring-boot-starter</artifactId>
				<version>${druid-spring-boot-starter.version}</version>
			</dependency>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-configuration-processor</artifactId>
				<version>${spring-boot-starter-parent.version}</version>
				<optional>true</optional>
			</dependency>
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-actuator</artifactId>
				<version>${spring-boot-starter-parent.version}</version>
			</dependency>
			<dependency>
				<groupId>com.alibaba.boot</groupId>
				<artifactId>dubbo-spring-boot-starter</artifactId>
				<version>${dubbo-spring-boot-starter.version}</version>
			</dependency>
			<dependency>
				<groupId>com.alibaba</groupId>
				<artifactId>dubbo</artifactId>
				<version>${dubbo.version}</version>
			</dependency>
			<dependency>
				<groupId>com.thoughtworks.xstream</groupId>
				<artifactId>xstream</artifactId>
				<version>${xstream.version}</version>
			</dependency>
			<dependency>
				<groupId>commons-beanutils</groupId>
				<artifactId>commons-beanutils</artifactId>
				<version>${commons-beanutils.version}</version>
			</dependency>
			<dependency>
				<groupId>org.javassist</groupId>
				<artifactId>javassist</artifactId>
				<version>${javassist.version}</version>
			</dependency>
			<dependency>
				<groupId>org.apache.curator</groupId>
				<artifactId>curator-framework</artifactId>
				<version>${curator-framework.version}</version>
			</dependency>
			<dependency>
				<groupId>org.apache.curator</groupId>
				<artifactId>curator-recipes</artifactId>
				<version>${curator-recipes.version}</version>
			</dependency>
			<dependency>
				<groupId>com.alibaba</groupId>
				<artifactId>fastjson</artifactId>
				<version>${fastjson.version}</version>
			</dependency>
			<dependency>
				<groupId>org.apache.commons</groupId>
				<artifactId>commons-pool2</artifactId>
				<version>${commons-pool2.version}</version>
			</dependency>
			<dependency>
				<groupId>org.apache.zookeeper</groupId>
				<artifactId>zookeeper</artifactId>
				<version>${zookeeper.version}</version>
			</dependency>
			<dependency>
				<groupId>javax.servlet</groupId>
				<artifactId>javax.servlet-api</artifactId>
				<version>${javax.servlet-api.version}</version>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-maven-plugin</artifactId>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
           

至此,父項目編寫完畢。

編寫服務接口子產品

滑鼠選中

springboot-dubbo

項目,單擊滑鼠右鍵,選擇建立一個

maven module

超詳細springboot整合dubbo

點選

next

按鈕,進入下一步

超詳細springboot整合dubbo

填寫項目子產品名稱為

springboot-dubbo-service

,點選

next

超詳細springboot整合dubbo

這裡

Group Id

與父項目保持一緻,

Packaging

選擇

jar

,因為服務接口不涉及

web

相關,是以将打包方式設為

jar

即可。填寫好資訊後點選

Finish

即可完成接口子產品的建立。

我們在接口項目中定義一個User實體類

package com.gavin.dubbo.pojo;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable{

	private Integer userId;

	private String userName;

	private String password;

	private Date createTime;

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	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;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

}
           

注意,被dubbo所使用的實體類必須要實作序列化接口,不然

dubbo

運作時會報錯。

接下來我們建立一個dubbo接口UserDubboService,接口中有兩個方法分别用于插入使用者和查詢使用者清單

package com.gavin.dubbo.service;

import java.util.List;

import com.gavin.dubbo.pojo.User;

public interface UserDubboService {
	
	public int insertUser(User user);
	
	public List<User> selectUsers(User user);
	
}
           

至此,服務接口項目就編寫完成了。

PS:在實際開發中,pojo也可以單獨建立一個子產品,專門用來存放實體類,然後在接口子產品中引入pojo子產品。
           

編寫服務提供者子產品

服務提供者子產品,也就是對接口子產品的實作。同樣的我們在

springboot-dubbo

中建立一個名稱為

springboot-dubbo-service-impl

的子產品,建立方法和接口子產品相同,在此不再贅述,唯一要注意的點是打包類型的選擇,服務實作即可以打

jar

成包釋出,也可以打成

war

包釋出

  1. 如果想要部署在

    tomcat

    web

    容器中運作,則需要打成

    war

    包,打包類型選擇

    war

  2. 如果直接以

    jar

    包的方式部署,則打包類型選擇

    jar

這裡我使用

war

的方式來進行開發,個人還是比較習慣部署在

tomcat

中運作,便于修改配置容器參數、啟停服務、檢視日志等操作。

編寫pom檔案内容,使用到的依賴如下

<!-- 打包方式,如想打成jar包,則改為jar -->
	<packaging>war</packaging>


	<dependencies>
		<!-- 引入springboot-dubbo-service接口項目 -->
		<dependency>
			<groupId>com.gavin</groupId>
			<artifactId>springboot-dubbo-service</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<exclusions>
				<!-- 排除自帶的logback依賴 -->
				<exclusion>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- 啟用log4j -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-log4j</artifactId>
		</dependency>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <!-- 部署時不使用 -->
            <scope>provided</scope>	
        </dependency>
        <dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>com.alibaba.boot</groupId>
			<artifactId>dubbo-spring-boot-starter</artifactId>
			<exclusions>
				<exclusion>
					<artifactId>zookeeper</artifactId>
					<groupId>org.apache.zookeeper</groupId>
				</exclusion>
				<exclusion>
					<groupId>com.alibaba</groupId>
					<artifactId>dubbo</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
		</dependency>
		<dependency>
			<groupId>com.thoughtworks.xstream</groupId>
			<artifactId>xstream</artifactId>
		</dependency>
		<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
		</dependency>
		<dependency>
			<groupId>dom4j</groupId>
			<artifactId>dom4j</artifactId>
		</dependency>
		<dependency>
			<groupId>org.javassist</groupId>
			<artifactId>javassist</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-recipes</artifactId>
			<exclusions>
				<exclusion>
					<groupId>org.apache.zookeeper</groupId>
					<artifactId>zookeeper</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
		</dependency>
	</dependencies>
           

建立spring配置檔案application.yml,内容如下,其中資料庫使用的是

mysql

,資料庫連接配接池使用的是阿裡druid

spring:
  profiles:
    active: dev
    

---
#開發環境

#伺服器相關配置
server:
  port: 8080
  tomcat:
    uri-encoding: UTF-8

#mybatis配置
mybatis:
  mapper-locations: classpath:mapper/*.xml    
#spring配置
spring:
  profiles: dev
  http:
    encoding:
      charset: UTF-8
      enabled: true
      force: true
  aop:
    auto: true
  #資料源
  datasource:
    druid:
      filters: mergeStat,wall
      initial-size: 5
      max-active: 50
      min-idle: 5
      max-wait: 6000
      validation-query: SELECT 'x'
      test-on-borrow: true
      test-on-return: true
      test-while-idle: true
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      remove-abandoned: true
      remove-abandoned-timeout: 1800
      log-abandoned: true
      web-stat-filter:
        enabled: true
        url-pattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*'
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*
        reset-enable: false
        login-username: admin
        login-password: 123456
      dubbo:
        url: jdbc:mysql://localhost:3306/dubbo?characterEncoding=utf8&serverTimezone=CTT
        username: root
        password: root
        driverClassName: com.mysql.cj.jdbc.Driver

#dubbo配置        
dubbo: 
  registry: 
    address: zookeeper://localhost:2181
  protocol:
    address: localhost
    port: 38080
           

建立

log4j.properties

檔案,這裡我是用的是

log4j

架構,使用

logback

也可,可以根據自己需要修改,配置内容如下

#set log levels
log4j.rootLogger = INFO , console , debug , error

#console
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH\:mm\:ss} [%p]-[%c] [%l] %m%n
 
#log file
log4j.appender.debug = org.apache.log4j.DailyRollingFileAppender
log4j.appender.debug.File = ${user.home}/app/logs/springboot-dubbo-service.log
log4j.appender.debug.Append = true
log4j.appender.debug.Threshold = debug
log4j.appender.debug.layout = org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern = %-d{yyyy-MM-dd HH\:mm\:ss} [%p]-[%c] [%l] %m%n
 
#exception
log4j.appender.error = org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.File = ${user.home}/app/logs/springboot-dubbo-service_error.log
log4j.appender.error.Append = true
log4j.appender.error.Threshold = ERROR
log4j.appender.error.layout = org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern = %-d{yyyy-MM-dd HH\:mm\:ss} [%p]-[%c] [%l] %m%n
 
 
#stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %l %c%n%p: %m%n
ˆ†
#jdbc
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Connection = DEBUG
log4j.logger.java.sql.Statement = DEBUG
log4j.logger.java.sql.PreparedStatement = DEBUG
log4j.logger.java.sql.ResultSet = DEBUG

#jdbcTemplate
log4j.logger.com.crtis.ktwechat.mapper=DEBUG
log4j.logger.org.springframework.jdbc.core.JdbcTemplate=debug
log4j.logger.org.springframework.jdbc.core.StatementCreatorUtils=Trace
           

接下來編寫

springboot

項目啟動類

DubboServiceApplication

以及

ServletInitializer

,其中後者用于

tomcat

容器中啟動

springboot

項目

package com.gavin.dubbo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;

@SpringBootApplication
@DubboComponentScan("com.gavin.dubbo.service.impl")	// 掃描注冊dubbo服務
public class DubboServiceApplication {
	public static void main(String[] args) {
		SpringApplication.run(DubboServiceApplication.class, args);
	}
}

           
package com.gavin.dubbo;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

/**
 * @title 用于tomcat啟動springboot程式
 * @author gavin
 * @date 2019年8月27日
 */
public class ServletInitializer extends SpringBootServletInitializer {
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(DubboServiceApplication.class);
	}
}

           

建立資料源,代碼如下

package com.gavin.dubbo.cfg.db;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;


/**
 * @title 建立資料源
 * @author gavin
 * @date 2019年8月27日
 */
@Configuration
@MapperScan(basePackages= {"com.gavin.dubbo.mapper"})	// 掃描mapper接口
public class DruidConfiguration {
	
	@ConfigurationProperties(prefix="spring.datasource.druid.dubbo")
	@Bean(name="dubbo")
	public DataSource dataSource() throws SQLException{
		return DruidDataSourceBuilder.create().build();
	}
}
           

編寫dubbo服務配置類DubboConfiguration,代碼如下,代碼注釋中有各項配置的詳細說明

package com.gavin.dubbo.cfg.dubbo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;

/**
 * @title dubbo服務配置
 * @author gavin
 * @date 2019年8月27日
 */
@Configuration
public class DubboConfiguration {
	
	// 注冊中心位址
	@Value("${dubbo.registry.address}")
	private String registryAddress;
	
	// dubbo服務位址
	@Value("${dubbo.protocol.address}")
	private String protocolAddress;
	
	// dubbo服務端口
	@Value("${dubbo.protocol.port}")
	private int protocolPort;
	
	
	/**
	 * @title 服務配置
	 * @author gavin
	 * @date 2019年8月27日
	 * @return
	 */
	@Bean
	public ApplicationConfig applicationConfig() {
		ApplicationConfig applicationConfig = new ApplicationConfig();
		// 指定一個服務名
		applicationConfig.setName("springboot-dubbo-service");
		// 設定Qos端口并且關閉,防止運作過程報錯
		applicationConfig.setQosEnable(false);
		applicationConfig.setQosAcceptForeignIp(false);
		applicationConfig.setQosPort(22222);
		return applicationConfig;
	}
	
	/**
	 * @title 注冊中心配置
	 * @author gavin
	 * @date 2019年8月27日
	 * @return
	 */
	@Bean
	public RegistryConfig registryConfig() {
		RegistryConfig  registryConfig = new RegistryConfig();
		registryConfig.setAddress(this.registryAddress);
		// 指定連接配接zookeeper的用戶端
		registryConfig.setClient("curator");
		// 設定逾時時間
		registryConfig.setTimeout(30000);
		return registryConfig;
	}
	
	/**
	 * @title 協定配置
	 * @author gavin
	 * @date 2019年8月30日
	 * @return
	 */
	@Bean
	public ProtocolConfig protocalConfig() {
		ProtocolConfig protocolConfig = new ProtocolConfig();
		// 指定協定為dubbo
		protocolConfig.setName("dubbo");
		// 指定dubbo服務位址
		protocolConfig.setHost(this.protocolAddress);
		// 指定dubbo服務端口
		protocolConfig.setPort(this.protocolPort);
		return protocolConfig;
	}

	public String getRegistryAddress() {
		return registryAddress;
	}

	public void setRegistryAddress(String registryAddress) {
		this.registryAddress = registryAddress;
	}

	public String getProtocolAddress() {
		return protocolAddress;
	}

	public void setProtocolAddress(String protocolAddress) {
		this.protocolAddress = protocolAddress;
	}

	public int getProtocolPort() {
		return protocolPort;
	}

	public void setProtocolPort(int protocolPort) {
		this.protocolPort = protocolPort;
	}
}

           

再建立dubbo服務銷毀類DubboPreDestory,

用于解決dubbo服務部署在tomcat中,tomcat自動重新開機時端口占用錯誤

package com.gavin.dubbo.cfg.dubbo;

import javax.annotation.PreDestroy;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.alibaba.dubbo.registry.dubbo.DubboRegistryFactory;
import com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol;

/**
 * @title dubbo服務銷毀配置,用于解決dubbo服務部署在tomcat中,tomcat自動重新開機時端口占用錯誤
 * @author gavin
 * @date 2019年8月27日
 */
@Component
public class DubboPreDestory {
	
	private Logger logger = Logger.getLogger(this.getClass());
	
	@PreDestroy
	public void destroy() {
		logger.info("dubbo執行個體銷毀中....");
		DubboRegistryFactory.destroyAll();
		DubboProtocol.getDubboProtocol().destroy();
		logger.info("dubbo服務銷毀完成!");
	}
}

           

建立UserMapper接口,代碼如下

package com.gavin.dubbo.mapper;

import java.util.List;

import com.gavin.dubbo.pojo.User;

public interface UserMapper {
	
	public int insert(User user);
	
	public List<User> select(User user);
}
           

建立UserMapper.xml檔案,内容如下

<?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.gavin.dubbo.mapper.UserMapper">
	<insert id="insert" parameterType="com.gavin.dubbo.pojo.User">
		INSERT INTO user 
		(
			userName
			,password
			,createTime
		)
		VALUES
		(
			#{userName}
			,#{password}
			,now()
		)
	</insert>
	
	<select id="select" parameterType="com.gavin.dubbo.pojo.User" resultType="com.gavin.dubbo.pojo.User">
		SELECT userId
		,userName
		,createTime
		FROM user
		<trim prefix="where" prefixOverrides="and|or|AND|OR">
			<if test="userName != null and userName != '' ">
				and userName = #{userName}
			</if>
		</trim>
	</select>
</mapper>
           

接下來建立dubbo服務實作類,實作UserDubboService

package com.gavin.dubbo.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.dubbo.config.annotation.Service;
import com.gavin.dubbo.mapper.UserMapper;
import com.gavin.dubbo.pojo.User;
import com.gavin.dubbo.service.UserDubboService;

@Component
@Service
public class UserDubboServiceImpl implements UserDubboService{
	@Autowired
	private UserMapper userMapper;
	
	@Override
	public int insertUser(User user) {
		return userMapper.insert(user);
	}

	@Override
	public List<User> selectUsers(User user) {
		return userMapper.select(user);
	}	
}
           

注意: dubbo服務實作中的@Service注解是com.alibaba.dubbo.config.annotation.Service,不要引成spring的。

至此,服務提供者項目就編寫完成了。

編寫消費者子產品

springboot-dubbo

中建立一個名稱為

springboot-dubbo-customer

的子產品,建立完成後開始編寫代碼。

首先引入pom依賴,需要注意的是,消費者也需要引入springboot-dubbo-service接口子產品

<dependencies>
		<!-- 引入springboot-dubbo-service接口項目 -->
		<dependency>
			<groupId>com.gavin</groupId>
			<artifactId>springboot-dubbo-service</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba.boot</groupId>
			<artifactId>dubbo-spring-boot-starter</artifactId>
			<exclusions>
				<exclusion>
					<artifactId>zookeeper</artifactId>
					<groupId>org.apache.zookeeper</groupId>
				</exclusion>
				<exclusion>
					<groupId>com.alibaba</groupId>
					<artifactId>dubbo</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
		</dependency>
		<dependency>
			<groupId>org.javassist</groupId>
			<artifactId>javassist</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-recipes</artifactId>
			<exclusions>
				<exclusion>
					<groupId>org.apache.zookeeper</groupId>
					<artifactId>zookeeper</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
		</dependency>
	</dependencies>
           

接着建立spring配置檔案 application.yml ,内容如下

spring:
  profiles:
    active: dev
    

---
#開發環境

#伺服器相關配置
server:
  port: 8081
  tomcat:
    uri-encoding: UTF-8
    
#dubbo配置    
dubbo:
  registry:
    address: zookeeper://localhost:2181
           

dubbo消費者配置類代碼

package com.gavin.customer.cfg;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.RegistryConfig;

@Configuration
public class DubboConfiguration {
	
	// 注冊中心位址
	@Value("${dubbo.registry.address}")
	private String registryAddress;
	
	/**
	 * @title 服務配置
	 * @author gavin
	 * @date 2019年8月30日
	 * @return
	 */
	@Bean
	public ApplicationConfig applicationConfig() {
		ApplicationConfig applicationConfig = new ApplicationConfig();
		applicationConfig.setName("springboot-dubbo-service");
		applicationConfig.setQosAcceptForeignIp(false);
		applicationConfig.setQosEnable(false);
		applicationConfig.setQosPort(55555);
		return applicationConfig;
	}
	
	/**
	 * @title 消費者配置
	 * @author gavin
	 * @date 2019年8月30日
	 * @return
	 */
	@Bean
	public ConsumerConfig consumerConfig() {
		ConsumerConfig  consumerConfig = new ConsumerConfig();
		// 設定逾時時間
		consumerConfig.setTimeout(15000);
		// 設定啟動時不監聽provider的狀态
		consumerConfig.setCheck(false);
		return consumerConfig;
	}
	
	/**
	 * @title 注冊中心配置
	 * @author gavin
	 * @date 2019年8月30日
	 * @return
	 */
	@Bean
	public RegistryConfig registryConfig() {
		RegistryConfig registryConfig = new RegistryConfig();
		registryConfig.setAddress(this.registryAddress);
		registryConfig.setClient("curator");
		registryConfig.setTimeout(15000);
		return registryConfig;
	}

	public String getRegistryAddress() {
		return registryAddress;
	}

	public void setRegistryAddress(String registryAddress) {
		this.registryAddress = registryAddress;
	}
}
           

接下來建立UserService接口,代碼如下

package com.gavin.customer.service;

import java.util.List;

import com.gavin.dubbo.pojo.User;

public interface UserService {

	int insert(User user) throws Exception;

	List<User> select(User user) throws Exception;

}

           

編寫UserService實作類

package com.gavin.customer.service.impl;

import java.util.List;

import org.springframework.stereotype.Service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.gavin.customer.service.UserService;
import com.gavin.dubbo.pojo.User;
import com.gavin.dubbo.service.UserDubboService;

@Service
public class UserServiceImpl implements UserService{
	
	@Reference
	private UserDubboService userDubboService;
	
	@Override
	public int insert(User user) throws Exception {
		return userDubboService.insertUser(user);
	}

	@Override
	public List<User> select(User user) throws Exception {
		return userDubboService.selectUsers(user);
	}

}
           

注意:

  1. @Service 注解是spring架構的,而不是dubbo
  2. @Reference是dubbo注解,用來注入dubbo服務

最後建立UserController,在裡面使用UserService

package com.gavin.customer.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import com.gavin.customer.service.UserService;
import com.gavin.dubbo.pojo.User;

@RestController
public class UserController {
	
	@Autowired
	private UserService userService;
	
	@PostMapping("user/add")
	public int addUser(User user) {
		try {
			return this.userService.insert(user);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	@GetMapping("user/list")
	public List<User> listUser(User user){
		try {
			return this.userService.select(user);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
}
           

UserController中申明了兩個接口

  1. user/add,用于添加單個使用者
  2. user/list ,查詢庫中所有使用者

至此,消費者項目編寫完畢。

測試

接下來就是測試消費者中的接口能否正确調用dubbo服務,我們依次啟動

  1. zookeeper
  2. dubbo服務方(springboot-dubbo-service-impl)
  3. 消費者(springboot-dubbo-customer)

啟動完成後,使用postman測試user/add接口,如下圖所示,點選send按鈕

超詳細springboot整合dubbo
超詳細springboot整合dubbo

接口傳回值為1,且資料庫中有一條新的記錄,說明接口調用成功。

調用user/list接口,結果如下圖。

超詳細springboot整合dubbo

測試完畢!