在开始文章之前,首先声明
在使用spring时会利用Spring的IOC原理,采用注解方式往spring容器中注入Bean,其中有一个@Service注解,但它有两种类型,下面分别讲解:
org.springframework.stereotype.Service |
归属:spring
作用:只是用来表示此类是业务层组件
spring配置文件:
<!-- 配置包扫描器 -->
<context:component-scan base-package="cn.e3mall.service"/>
常用的作用在类上的注解,还有以下几种:
以上所有的的作用在类上的注解,归根到底,都是讲注解的类纳入到spring容器进行管理,之所以名字不同,只是表示组件的名称不同,就如世上所有的人都有名字(注解名),但他们都是人(标识为组件,放到spring容器)
com.alibaba.dubbo.config.annotation.Service |
归属:dubbo
作用:是dubbo用来声明provider的注解(即声明该类是服务的提供者的注解)
spring配置文件:
<!-- 配置包扫描器,alibaba的@Service注解 -->
<dubbo:annotation package="cn.e3mall.service" />
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="e3-manager" />
<dubbo:registry protocol="zookeeper" address="192.168.20.191:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
如果你的程序是分布式程序,且使用的dubbo实现的RPC,可以有两种配置:
服务的提供者 |
第一种:仍然使用spring的@Service
必须在spring配置文件中非注解的方式显示暴露一下服务接口,存在的弊端:如果有好多服务提供者,要在spring配置文件中写好多dubbo:service,配置如下:
<!-- 配置包扫描器,spring的@Service注解 -->
<context:component-scan base-package="cn.e3mall.service"/>
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="e3-manager" />
<dubbo:registry protocol="zookeeper" address="192.168.20.191:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="cn.e3mall.service.ItemService" ref="itemServiceImpl" timeout="600000"/>
第二种:使用alibaba的dubbo的@Service
此时就不需要在spring配置文件中显示声明要暴露的服务接口了,spring配置文件中省去好多dubbo:service,配置如下:
<!-- 配置包扫描器,alibaba的@Service注解 -->
<dubbo:annotation package="cn.e3mall.service" />
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="e3-manager" />
<dubbo:registry protocol="zookeeper" address="192.168.20.191:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
服务的消费者 |
第一种:使用@Reference引用服务
spring配置文件如下:
<!-- 配置包扫描器 -->
<dubbo:annotation package="cn.e3mall.controller" />
<!-- 引用dubbo服务 -->
<dubbo:application name="e3-manager-web"/>
<dubbo:registry protocol="zookeeper" address="192.168.20.191:2181"/>
Controller类上面使用@Reference表明我要引用的服务
<!-- 也是alibaba的注解-->
import com.alibaba.dubbo.config.annotation.Reference;
@Reference
private ItemService itemService;
第二种:使用@Autowired引用服务
如果你非要使用@Autowired注解,也是可以的,需要在spring配置文件中显示的声明调用的dubbo服务,但是不推荐,因为:
1、当你配置的引用的服务没有提供者是,编译阶段就会出错,因为@Autowired默认的去找bean,没有找到对应的bean,就去你引用的dubbo服务中去找,但是这是没有提供者,即没有这个真正的类,所以编译就报错了;而用alibaba的@Service只是一个引用,它能找到这个引用,但是如果没有提供者,也会报错ERROR,显示No Provider没有提供者,但是能编译过去项目能正常运行
2、如果引用的dubbo服务非常多的话,spring配置文件要写好多的dubbo:reference
spring配置文件:
<!-- spring的@service -->
<context:component-scan base-package="cn.e3mall.controller" />
<!-- 引用dubbo服务 -->
<dubbo:application name="e3-manager-web"/>
<dubbo:registry protocol="zookeeper" address="192.168.20.191:2181"/>
<dubbo:reference interface="cn.e3mall.service.ItemService" id="itemService" />
Controller类上面使用@Autowired表明我要引用的服务
import org.springframework.beans.factory.annotation.Autowired;
@Autowired
private ItemService itemService;
【总结】
我们在使用dubbo服务时,还是采用正规的做法,服务提供者使用alibaba提供的dubbo提供的注解@Service,服务消费者使用@Reference引用服务。在研究这个知识点时,就在服务提供者和消费者上来回换@Service,@Reference,@Autowired,包括扫描包的方式,把各种情况都组合了一遍,然后把每种组合出现的问题也相应的记下来,然后总结,还是不明白,最后在师父的帮助下,顺利解决,很感谢师父。