创建一个 maven 多模块项目,结构如下:
dubbo-annotation-with-springmvc-sample(父模块) | |__ user-module-api(服务接口模块) | |__ user-module-provider(服务提供者) | |__ user-module-consumer(服务消费者)
dubbo-annotation-with-springmvc-sample/pom.xml 配置如下:
<projectxmlns="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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.fanlychie</groupId>
<artifactId>dubbo-annotation-with-springmvc-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>dubbo-annotation-with-springmvc-sample</name>
<description>Sample project for Dubbo</description>
<url>http://maven.apache.org</url>
<modules>
<module>user-module-api</module>
<module>user-module-provider</module>
<module>user-module-consumer</module>
</modules>
<properties>
<dubbo.version>2.5.3</dubbo.version>
<spring.version>4.3.7.RELEASE</spring.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.fanlychie</groupId>
<artifactId>user-module-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<!-- dubbo依赖的spring版本(2.5)较低, 排除此依赖, 使用自己的spring版本 -->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
user-module-api/pom.xml 配置如下:
<projectxmlns="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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fanlychie</groupId>
<artifactId>dubbo-annotation-with-springmvc-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>user-module-api</artifactId>
<packaging>jar</packaging>
<name>user-module-api</name>
<url>http://maven.apache.org</url>
</project>
编写注册用户的示例服务接口:
package org.fanlychie.service;
public interface UserService{
void register(String username, String password);
}
user-module-provider/pom.xml 配置如下:
<projectxmlns="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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fanlychie</groupId>
<artifactId>dubbo-annotation-with-springmvc-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>user-module-provider</artifactId>
<packaging>jar</packaging>
<name>user-module-provider</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.fanlychie</groupId>
<artifactId>user-module-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 打包配置, 输出可执行的 jar 包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>com.alibaba.dubbo.container.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</plugin>
</plugins>
</build>
</project>
实现服务接口,使用 com.alibaba.dubbo.config.annotation.@Service
注解暴露服务:
package org.fanlychie.service;
import com.alibaba.dubbo.config.annotation.Service;
@Service
public class UserServiceImplimplements UserService{
@Override
public void register(String username, String password){
System.out.println("---------------------------------------------------------");
System.out.println(String.format("接收到注册用户请求 - {username:%s, password:%s}",
username, password));
System.out.println("---------------------------------------------------------");
}
}
user-module-provider/src/main/resources/dubbo.properties 配置如下:
dubbo.spring.config=classpath:spring-dubbo-provider.xml
user-module-provider/src/main/resources/spring-dubbo-provider.xml 配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beansxmlns="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:applicationname="user-module-provider"/>
<!-- 使用ZK注册中心暴露服务地址 -->
<dubbo:registryaddress="zookeeper://127.0.0.1:2181"/>
<!-- 用Dubbo协议在20880端口暴露服务 -->
<dubbo:protocolname="dubbo"port="20880"/>
<!-- 扫描注解包路径,多个包用逗号分隔 -->
<dubbo:annotationpackage="org.fanlychie.service"/>
</beans>
user-module-provider/src/main/resources/log4j.properties 配置如下:
log4j.rootCategory = INFO, 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:SSS} [%t] %-5p [%c{1}:%L] - %m%n
user-module-consumer/pom.xml 配置如下:
<projectxmlns="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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fanlychie</groupId>
<artifactId>dubbo-annotation-with-springmvc-sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>user-module-consumer</artifactId>
<packaging>war</packaging>
<name>user-module-consumer</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.fanlychie</groupId>
<artifactId>user-module-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
</dependency>
</dependencies>
<build>
<finalName>autosellrobot-wechat</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<path>/</path>
<port>8080</port>
<uriEncoding>UTF-8</uriEncoding>
<url>http://localhost:8080/manager/html</url>
</configuration>
</plugin>
</plugins>
</build>
</project>
服务消费者使用 com.alibaba.dubbo.config.annotation.@Reference
注解引用接口服务:
import com.alibaba.dubbo.config.annotation.Reference;
import org.fanlychie.service.UserService;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController{
@Reference
private UserService userService;
@GetMapping("/user/register")
publicStringregister(String username, String password){
if (!StringUtils.hasText(username) || !StringUtils.hasText(password)) {
return "用户名或密码不能为空";
}
userService.register(username, password);
return "注册完成";
}
}
user-module-consumer/src/main/webapp/WEB-INF/web.xml 配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-appversion="2.5"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
user-module-consumer/src/main/resources/log4j.properties 配置如下:
log4j.rootCategory = INFO, 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:SSS} [%t] %-5p [%c{1}:%L] - %m%n
user-module-consumer/src/main/resources/spring-context.xml 配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:component-scanbase-package="org.fanlychie"/>
</beans>
user-module-consumer/src/main/resources/spring-mvc.xml 配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:applicationname="user-module-consumer"/>
<!-- 使用ZK注册中心暴露服务地址 -->
<dubbo:registryaddress="zookeeper://127.0.0.1:2181"/>
<!-- 扫描注解包路径,多个包用逗号分隔 -->
<dubbo:annotationpackage="org.fanlychie.controller"/>
<beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<propertyname="useSuffixPatternMatch"value="true"/>
<propertyname="useTrailingSlashMatch"value="true"/>
</bean>
<beanid="stringHttpMessageConverter"class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-argvalue="UTF-8"/>
<propertyname="supportedMediaTypes">
<list>
<value>text/html;charset=utf-8</value>
<value>application/xml;charset=utf-8</value>
<value>application/json;charset=utf-8</value>
</list>
</property>
</bean>
<beanid="mappingJackson2HttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<propertyname="prefixJson"value="false"/>
<propertyname="supportedMediaTypes">
<list>
<value>text/html;charset=utf-8</value>
<value>application/xml;charset=utf-8</value>
<value>application/json;charset=utf-8</value>
</list>
</property>
</bean>
<beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<propertyname="messageConverters">
<list>
<refbean="stringHttpMessageConverter"/>
<refbean="mappingJackson2HttpMessageConverter"/>
</list>
</property>
</bean>
<context:component-scanbase-package="org.fanlychie.**.controller"/>
</beans>
服务消费者方 dubbo 注解扫描配置的信息不能独立出 springmvc 配置文件,否则 @Reference
注解引用的接口实例会出现 Null 的状况。
示例项目开发环境:Java-8、Maven-3、IntelliJ IDEA-2017、Spring-4.7、Dubbo-2.5.3
完整示例项目链接: dubbo-annotation-with-springmvc-sample
参考文档文献链接: dubbo用户指南