Dubbo服务化的最佳实践:
-
将暴露的服务接口、服务模型(实体bean对象)均放在公共包里,因为消费者需要知道这些信息
-
粒度:
- 服务接口尽可能大粒度,每个服务方法代表一个功能,而不是某功能的一个步骤。其实就是之前写的service层
- 服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸
- 不建议使用过于抽象的通用接口,如Map query(Map),这样的接口没有明确语义,根本不知道Map里存什么,存多少,后期维护以及别人调用都不方便
-
版本,每个接口都定义版本号,区分统一接口的不同实现,比如<dubbo:service interface=“com.xxx.xxxService” version=“1.0” />
下面将分三个模块对刚刚的例子进行优化,因为Dubbo官方推荐将实体bean和业务接口单独放一个接口工程中。
link_interface
其中link_interface不需要引什么依赖,只要把接口和bean写好就行,代码还是之前的:
link_provider
link_provider则除了引入spring,dubbo的依赖,还需要引入这个接口工程的依赖,因为需要实现这个接口工程
UserSereviceImpl
public class UserServiceImpl implements UserSesrvice {
@Override
public User queryUserById(Integer id) {
User user = new User();
user.setId(id);
user.setUsername("Bob");
return user;
}
@Override
public Integer queryAllUserCount() {
return 100;
}
}
dubbo_provider的配置文件和之前一样
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 声明dubbo服务提供者的名称,保证唯一性-->
<dubbo:application name="dubbo_provider" />
<!-- 设置dubbo使用的协议和端口号-->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 暴露服务接口-->
<dubbo:service interface="cn.youkee.service.UserSesrvice" ref="userService" registry="N/A" />
<!-- 接在业务接口的实现类到spring容器中-->
<bean id="userService" class="cn.youkee.service.UserServiceImpl"/>
</beans>
同样需要配置监听器,加载spring容器和读取配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dubbo_provider.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app >
link_consumer
同样需要在pom文件中引入接口工程,Controller调用service,实现业务功能:
@Controller
public class UserController {
@Resource
private UserSesrvice userSesrvice;
@RequestMapping("/userDetail")
public String userDetail(Model model, Integer id) {
User user = userSesrvice.queryUserById(id);
Integer count = userSesrvice.queryAllUserCount();
model.addAttribute("user", user);
model.addAttribute("count", count);
return "userDetail";
}
}
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: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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="cn.youkee.controller" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
dubbo_consumer.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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 声明消费者名称-->
<dubbo:application name="dubbo_consumer" />
<!-- 引用远程接口服务-->
<dubbo:reference id="userService" interface="cn.youkee.service.UserSesrvice" registry="N/A" url="dubbo://localhost:20880"/>
</beans>
配置DispatcherServlet:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<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:applicationContext.xml, classpath:dubbo_consumer.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app >
tomcat的配置还是和之前一样,需要注意端口冲突的问题,然后分别启动provider和consumer的tomcat,在浏览器访问userDetail,并带上参数id,可以看到调用的结果。这比之前的实现更符合Dubbo的官方规范,即只暴露接口,不需要再打jar包,而且调用方也无法在本地new一个Impl类。