Dubbo API 配置方式

前言

個人項目 AngBoot 使用的是 SpringSecurity 作權限管理與認證, 可是, 項目初衷是做爲開發模板結構, 因此, 爲了應對微服務以及更靈活的使用場景, 我引入了 Dubbo 以提供遠程認證服務. 這樣, 能夠經過修改配置很容易的從我內嵌的認證系統遷移到任何一個開發者本身的認證系統.html

今天在本身項目中引入 Dubbo 時遇到一個問題, 項目自己是 SpringBoot 項目, 若是須要 Dubbo 就可使用 @EnableDubbo 以及註解配置的方式方便的引入 Dubbo 到 SpringBoot 環境, 可是, 個人需求是須要配置化,靈活, 動態的引入 Dubbo rpc 遠程服務, 簡單的說就是默認使用內嵌的模塊, 可是依然能夠經過配置使用遠程服務, 因此直接爲 SpringBoot 添加 @EnableDubbo 直接的方式使用 Dubbo 顯得並非那麼合適, 由於默認並無遠程調用git

參看 Dubbo 文檔能夠發現Dubbo 的 API 配置方式, 可是官網寫的比較粗糙, 可是直覺猜想應該是能夠把 ApplicationConfig, RegistryConfig 等對象放入 IOC 中, 而後經過 ReferenceConfig 將遠程對象拿到並加入 IOC 中, 這樣就不會對其餘模塊和代碼產生影響. 因此寫個 exmaple 進行驗證.github

建立服務提供者 provider-ticket

服務提供者無所謂那種配置方式, 咱們就用最快最簡單的 SpringBoot + @EnableDubbo 註解進行配置.spring

  • SpringBoot 入口類
@SpringBootApplication
@EnableDubbo
public class ProviderTicketApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProviderTicketApplication.class, args);
    }

}複製代碼

  • 服務接口
package com.jack.ticket.service;

public interface TicketService {
    public String getTicket();
}
複製代碼

  • 服務實現
package com.jack.ticket.service;

import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;

@Component // 將服務加入 IOC
@Service // 將服務發佈出去
public class TicketServiceImpl implements TicketService {
    @Override
    public String getTicket() {
        return "厲害了, 個人國....";
    }
}複製代碼

  • Dubbo 配置
dubbo.application.name=provider-ticket

# 註冊中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181

# 包掃描須要提供的服務
dubbo.scan.base-packages=com.jack.ticket.service複製代碼

  • 開啓 Zookeeper, 啓動服務提供者 ProviderTicketApplication
    file

API 配置建立服務消費者 consumer-user-api

  • SpringBoot 入口類. 注意沒有 EnableDubbo 註解
@SpringBootApplication
public class ConsumerUserApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerUserApplication.class, args);
    }

}複製代碼

  • 遠程服務接口
package com.jack.ticket.service;

public interface TicketService {

    String getTicket();
}複製代碼

  • 建立一個 Configuration 類去獲取遠程服務
package com.jack.user.config;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.jack.ticket.service.TicketService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DubboConfiguration {

   /**
    * 建立 ApplicationConfig 對象.
    * 將其加入 IOC 並非必須的, 由於只有在獲取遠程對象時才須要該實例,
    * 所以, 當遠程服務較多須要屢次獲取時將該實例加入 IOC 才顯得有必要,
    * 固然, 你也能夠將其做爲成員屬性持有複用.
    */
   @Bean
   public ApplicationConfig applicationConfig() {
      ApplicationConfig application = new ApplicationConfig();
      application.setName("consumer-user");

      return application;
   }

   /**
    * 建立 RegistryConfig 以配置註冊中心信息.
    * @see DubboConfiguration#applicationConfig() 一樣的加入 IOC 不是必須的
    */
   @Bean
   public RegistryConfig registryConfig() {
      RegistryConfig registry = new RegistryConfig();
      registry.setAddress("zookeeper://127.0.0.1:2181");

      return registry;
   }

   /**
    * 獲取遠程服務對象.
    * 實際上, 若是遠程對象只調用一次, 也沒有必要加入 IOC, 在使用時獲取一次就行了,
    * 可是大部分場景都是須要屢次重複調用的, 並且獲取遠程服務對象的代價昂貴, 因此,
    * 將其加入 IOC 容器以複用很明顯是較好實踐, 獲取能夠自行緩存.
    */
   @Bean
   public TicketService ticketService() {
      // 此實例很重,封裝了與註冊中心的鏈接以及與提供者的鏈接,請自行緩存,不然可能形成內存和鏈接泄漏
      ReferenceConfig<TicketService> reference = new ReferenceConfig<>();
      reference.setApplication(applicationConfig());
      // 多個註冊中心能夠用setRegistries()
      reference.setRegistry(registryConfig());
      reference.setInterface(TicketService.class);

      // 和本地bean同樣使用 TicketService
      // 注意:此代理對象內部封裝了全部通信細節,對象較重,請緩存複用
      TicketService ticketService = reference.get();

      return ticketService;
   }
}複製代碼

  • 建立 UserService 使用遠程服務對象

因爲遠程服務對象已經被獲取並加入到當前 IOC 中, 因此就能夠經過 @Autowired 進行依賴注入.apache

package com.jack.user.service;

import com.jack.ticket.service.TicketService;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    public final TicketService ticketService;

    public UserService(TicketService ticketService) {
        this.ticketService = ticketService;
    }

    public void buyTicket() {
        String ticket = ticketService.getTicket();

        System.out.println("買到票了, ticket: " + ticket);
    }
}複製代碼

  • 運行測試
package com.jack.user.service;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTests {

    @Autowired
    private UserService userService;

    @Test
    public void testBuyTicket() {
        Assert.assertNotNull("init user service failed...", userService);
        userService.buyTicket();
    }

}複製代碼

file

總結

至此, Dubbo 的 API 配置方式就介紹完了, 咱們能夠在 Spring/SpringBoot 環境中方便的使用和配合 Spring 的 Conditional 靈活的進行擴展式編程以是本身的項目/產品能夠應對更多使用場景.編程

更多請關注個人項目 AngBootapi

平常求贊: 歡迎你們點贊, 評論, 關注, 轉發. 要是能給點讚揚就更好了, 哈哈哈.... blog.csdn.net/DreamLi1314緩存

相關文章
相關標籤/搜索