赞
踩
一个dubbo服务需要 api、provider、consumer构成
api提供接口供provider和consumer引用
1、接口的实现类需要用
org.apache.dubbo.config.annotation.Service包的@Service注解
- @Service(version = "1.0.1")
- public class ExampleImpl implements ExampleService {
-
- @Override
- public String sayHello() {
- return "new springboot dubbo project";
- }
- }
区别于Spring的@Service注解
2、接口的引用方需要
org.apache.dubbo.config.annotation.Reference包的@Reference
形如:
- //本地服务
- @Autowired
- LocalService localService;
- //dubbo服务
- @Reference
- ExampleService exampleService;
可能使用起来会有同学觉得不方便,无论是实现还是引用可不可以只用Spring的注解呢,这时需要ReferenceBean出马了
使用方法,由provider新建moduel-client供consumer调用,client引用api
- @Bean
- public ReferenceBean<PLConfigService> configServiceReferenceBean(){
- ReferenceBean<PLConfigService> referenceBean = new ReferenceBean<>();
- referenceBean.setInterface(PLConfigService.class);
- referenceBean.setCheck(false);
- return referenceBean;
- }
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {...}
ReferenceBean实现了InitializingBean接口的afterPropertiesSet(),所以Spring会在初始化该类的属性后调用afterPropertiesSet方法
入口:
- public void afterPropertiesSet() throws Exception {
- //加载ConsumerConfig
- if (getConsumer() == null) {
- Map<String, ConsumerConfig> consumerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ConsumerConfig.class, false, false);
- if (consumerConfigMap != null && consumerConfigMap.size() > 0) {
- ConsumerConfig consumerConfig = null;
- for (ConsumerConfig config : consumerConfigMap.values()) {
- if (config.isDefault() == null || config.isDefault().booleanValue()) {
- if (consumerConfig != null) {
- throw new IllegalStateException("Duplicate consumer configs: " + consumerConfig + " and " + config);
- }
- consumerConfig = config;
- }
- }
- if (consumerConfig != null) {
- setConsumer(consumerConfig);
- }
- }
- }
- //加载应用上下文
- if (getApplication() == null
- && (getConsumer() == null || getConsumer().getApplication() == null)) {
- Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
- if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
- ApplicationConfig applicationConfig = null;
- for (ApplicationConfig config : applicationConfigMap.values()) {
- if (config.isDefault() == null || config.isDefault().booleanValue()) {
- if (applicationConfig != null) {
- throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
- }
- applicationConfig = config;
- }
- }
- if (applicationConfig != null) {
- setApplication(applicationConfig);
- }
- }
- }
- //加载ModuleConfig
- if (getModule() == null
- && (getConsumer() == null || getConsumer().getModule() == null)) {
- Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
- if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
- ModuleConfig moduleConfig = null;
- for (ModuleConfig config : moduleConfigMap.values()) {
- if (config.isDefault() == null || config.isDefault().booleanValue()) {
- if (moduleConfig != null) {
- throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);
- }
- moduleConfig = config;
- }
- }
- if (moduleConfig != null) {
- setModule(moduleConfig);
- }
- }
- }
- //加载RegistryConfig
- if ((getRegistries() == null || getRegistries().size() == 0)
- && (getConsumer() == null || getConsumer().getRegistries() == null || getConsumer().getRegistries().size() == 0)
- && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) {
- Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
- if (registryConfigMap != null && registryConfigMap.size() > 0) {
- List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
- for (RegistryConfig config : registryConfigMap.values()) {
- if (config.isDefault() == null || config.isDefault().booleanValue()) {
- registryConfigs.add(config);
- }
- }
- if (registryConfigs != null && registryConfigs.size() > 0) {
- super.setRegistries(registryConfigs);
- }
- }
- }
- //加载MonitorConfig
- if (getMonitor() == null
- && (getConsumer() == null || getConsumer().getMonitor() == null)
- && (getApplication() == null || getApplication().getMonitor() == null)) {
- Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
- if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
- MonitorConfig monitorConfig = null;
- for (MonitorConfig config : monitorConfigMap.values()) {
- if (config.isDefault() == null || config.isDefault().booleanValue()) {
- if (monitorConfig != null) {
- throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);
- }
- monitorConfig = config;
- }
- }
- if (monitorConfig != null) {
- setMonitor(monitorConfig);
- }
- }
- }
- //以上config都在DubboAutoConfiguration中加载进了Spring容器中
- Boolean b = isInit();
- if (b == null && getConsumer() != null) {
- b = getConsumer().isInit();
- }
- if (b != null && b.booleanValue()) {
- //重点 这一步会将之前set的interface加载进来
- getObject();
- }
- }
- public Object getObject() throws Exception {
- return get();
- }
get()是父类ReferenceConfig<T>的方法,T为传入的接口的类型
- // 接口代理类引用
- private transient volatile T ref;
- public synchronized T get() {
- if (destroyed) {
- throw new IllegalStateException("Already destroyed!");
- }
- if (ref == null) {
- //初始化
- init();
- }
- return ref;
- }
我们setInterface时
- public void setInterface(Class<?> interfaceClass) {
- if (interfaceClass != null && !interfaceClass.isInterface()) {
- throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!");
- }
- this.interfaceClass = interfaceClass;
- setInterface(interfaceClass == null ? (String) null : interfaceClass.getName());
- }
-
- public void setInterface(String interfaceName) {
- this.interfaceName = interfaceName;
- if (id == null || id.length() == 0) {
- id = interfaceName;
- }
- }
- private void init() {
- //...省略N行
- //
- checkStubAndMock(interfaceClass);
- //...
- ref = createProxy(map);
- }
- private T createProxy(Map<String, String> map) {
- URL tmpUrl = new URL("temp", "localhost", 0, map);
- final boolean isJvmRefer;
- if (isInjvm() == null) {
- if (url != null && url.length() > 0) { //指定URL的情况下,不做本地引用
- isJvmRefer = false;
- } else if (InjvmProtocol.getInjvmProtocol().isInjvmRefer(tmpUrl)) {
- //默认情况下如果本地有服务暴露,则引用本地服务.
- isJvmRefer = true;
- } else {
- isJvmRefer = false;
- }
- } else {
- isJvmRefer = isInjvm().booleanValue();
- }
-
- if (isJvmRefer) {
- URL url = new URL(Constants.LOCAL_PROTOCOL, NetUtils.LOCALHOST, 0, interfaceClass.getName()).addParameters(map);
- invoker = refprotocol.refer(interfaceClass, url);
- if (logger.isInfoEnabled()) {
- logger.info("Using injvm service " + interfaceClass.getName());
- }
- } else {
- if (url != null && url.length() > 0) { // 用户指定URL,指定的URL可能是对点对直连地址,也可能是注册中心URL
- String[] us = Constants.SEMICOLON_SPLIT_PATTERN.split(url);
- if (us != null && us.length > 0) {
- for (String u : us) {
- URL url = URL.valueOf(u);
- if (url.getPath() == null || url.getPath().length() == 0) {
- url = url.setPath(interfaceName);
- }
- if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
- urls.add(url.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
- } else {
- urls.add(ClusterUtils.mergeUrl(url, map));
- }
- }
- }
- } else { // 通过注册中心配置拼装URL
- List<URL> us = loadRegistries(false);
- if (us != null && us.size() > 0) {
- for (URL u : us) {
- URL monitorUrl = loadMonitor(u);
- if (monitorUrl != null) {
- map.put(Constants.MONITOR_KEY, URL.encode(monitorUrl.toFullString()));
- }
- urls.add(u.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
- }
- }
- if (urls == null || urls.size() == 0) {
- throw new IllegalStateException("No such any registry to reference " + interfaceName + " on the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", please config <dubbo:registry address=\"...\" /> to your spring config.");
- }
- }
-
- if (urls.size() == 1) {
- invoker = refprotocol.refer(interfaceClass, urls.get(0));
- } else {
- List<Invoker<?>> invokers = new ArrayList<Invoker<?>>();
- URL registryURL = null;
- for (URL url : urls) {
- invokers.add(refprotocol.refer(interfaceClass, url));
- if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
- registryURL = url; // 用了最后一个registry url
- }
- }
- if (registryURL != null) { // 有 注册中心协议的URL
- // 对有注册中心的Cluster 只用 AvailableCluster
- URL u = registryURL.addParameter(Constants.CLUSTER_KEY, AvailableCluster.NAME);
- invoker = cluster.join(new StaticDirectory(u, invokers));
- } else { // 不是 注册中心的URL
- invoker = cluster.join(new StaticDirectory(invokers));
- }
- }
- }
-
- Boolean c = check;
- if (c == null && consumer != null) {
- c = consumer.isCheck();
- }
- if (c == null) {
- c = true; // default true
- }
- if (c && !invoker.isAvailable()) {
- throw new IllegalStateException("Failed to check the status of the service " + interfaceName + ". No provider available for the service " + (group == null ? "" : group + "/") + interfaceName + (version == null ? "" : ":" + version) + " from the url " + invoker.getUrl() + " to the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion());
- }
- if (logger.isInfoEnabled()) {
- logger.info("Refer dubbo service " + interfaceClass.getName() + " from url " + invoker.getUrl());
- }
- // 创建服务代理
- return (T) proxyFactory.getProxy(invoker);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。