個人項目 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
服務提供者無所謂那種配置方式, 咱們就用最快最簡單的 SpringBoot +
@EnableDubbo
註解進行配置.spring
@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.application.name=provider-ticket
# 註冊中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
# 包掃描須要提供的服務
dubbo.scan.base-packages=com.jack.ticket.service複製代碼
ProviderTicketApplication
@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();
}複製代碼
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;
}
}複製代碼
因爲遠程服務對象已經被獲取並加入到當前 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();
}
}複製代碼
至此, Dubbo 的 API 配置方式就介紹完了, 咱們能夠在 Spring/SpringBoot 環境中方便的使用和配合 Spring 的 Conditional 靈活的進行擴展式編程以是本身的項目/產品能夠應對更多使用場景.編程
更多請關注個人項目 AngBootapi
平常求贊: 歡迎你們點贊, 評論, 關注, 轉發. 要是能給點讚揚就更好了, 哈哈哈.... blog.csdn.net/DreamLi1314緩存