亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Spring Cloud Feign Clients 無需 Controller自動(dòng)暴露Restfu

GeekGhc / 1418人閱讀

摘要:前言在開發(fā)應(yīng)用中,作為聲明式調(diào)用的事實(shí)標(biāo)準(zhǔn)極大的簡化了遠(yuǎn)程調(diào)用,提供了類本地化的調(diào)用方式。本文介紹一種通過動(dòng)態(tài)代理的方式無需直接暴露接口。后語關(guān)于這個(gè)框架的介紹,后續(xù)詳細(xì)的給大家進(jìn)行介紹。

前言

在開發(fā)SpringCloud應(yīng)用中,F(xiàn)eign作為聲明式調(diào)用的事實(shí)標(biāo)準(zhǔn)極大的簡化了Rest遠(yuǎn)程調(diào)用,提供了類本地化的調(diào)用方式。服務(wù)提供方的接口暴露方式是通過Controller暴露Restful,而在這個(gè)Controller的代碼現(xiàn)實(shí)中大部分都是處理請求然后再調(diào)用Service中的方法,是一個(gè)比較模板化的功能,但是工作量確不少。本文介紹一種通過動(dòng)態(tài)代理的方式無需Controller直接暴露Restful接口。
本文中使用筆者在Github開源的框架來實(shí)現(xiàn),本文的講解也在這個(gè)框架基礎(chǔ)之上來說明
Git路徑:https://github.com/leecho/spr...

依賴
     
        com.github.leecho
        spring-cloud-starter-feign-proxy
        {last-version}
    
實(shí)現(xiàn) 定義Service Interface

首先定義服務(wù)接口,使用@FeignClient標(biāo)示是一個(gè)Feign接口,在這個(gè)示例Sevice中定義了CURD和文件上傳方法,并使用了一些常用參數(shù)注解

@Api(tags = "DemoService", description = "Demo Feign Client")
@FeignClient("demo-service")
public interface DemoService {

    /**
     * create demo
     *
     * @param demo
     * @return
     */
    @ApiOperation(value = "Create demo")
    @PostMapping(value = "/demo")
    Demo create(@RequestBody @Valid @ApiParam Demo demo);

    /**
     * update demo
     *
     * @param demo
     * @return
     */
    @PutMapping(value = "/demo")
    Demo update(@RequestBody @Valid Demo demo);

    /**
     * delete demo
     *
     * @param id
     * @return
     */
    @DeleteMapping(value = "/demo/{id}")
    Demo delete(@PathVariable(name = "id") String id);

    /**
     * list demo
     *
     * @param id
     * @param headerValue test header value
     * @return
     */
    @GetMapping(value = "/demo/{id}")
    Demo get(@PathVariable(name = "id") String id, @RequestHeader(name = "header") String headerValue);

    /**
     * list demos
     *
     * @return
     */
    @GetMapping(value = "/demos")
    List list();

    /**
     * upload file
     *
     * @param file
     * @return
     */
    @PostMapping(value = "/demo/upload")
    String upload(@RequestPart(name = "file") MultipartFile file);
}
實(shí)現(xiàn)Service

在實(shí)現(xiàn)類中簡單的實(shí)現(xiàn)了CURD和上傳文件的方法

@Slf4j
@Primary
@Service
public class DemoServiceImpl implements DemoService {

    @Override
    public Demo create(Demo demo) {
        log.info("Create executed : " + demo);
        return demo;
    }

    @Override
    public Demo update(Demo demo) {
        log.info("Update execute :" + demo);
        return demo;
    }

    @Override
    public Demo delete(String id) {
        log.info("Delete execute : " + id);
        return Demo.builder().name("demo-" + id).data("data-" + id).build();
    }

    @Override
    public Demo get(String id, String header) {
        Demo demo = Demo.builder()
                .name(header)
                .data(header).build();
        System.out.println("Get execute : " + id + "," + header);
        return demo;
    }

    @Override
    public List list() {
        System.out.println("List execute");
        List demos = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Demo demo = Demo.builder()
                    .name("demo-" + i)
                    .data("data" + i).build();
            demos.add(demo);
        }
        return demos;
    }

    @Override
    public String upload(MultipartFile file) {
        return file.getOriginalFilename();
    }
}
動(dòng)態(tài)生成Restful接口的原理是動(dòng)態(tài)生成Controller類實(shí)現(xiàn)ServiceInterface,如果真正的實(shí)現(xiàn)類會(huì)被其他BEAN依賴,需要通過注解@Primary來方式來防止依賴沖突
配置應(yīng)用

在應(yīng)用中通過@EnableFeignProxies來標(biāo)示應(yīng)用在啟動(dòng)的過程中會(huì)掃描所有的FeignClients并暴露Restful接口

@EnableFeignProxies(basePackages = "com.github.leecho")
@ComponentScan("com.github.leecho")
@SpringBootApplication
public class DemoApplication {

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

}
測試用例

在測試用例中對Service的接口進(jìn)行測試

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class DemoApplicationTest {
    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @Before
    public void setUp() {
        mvc = MockMvcBuilders.webAppContextSetup(context).build();
    }

    @Test
    public void create() throws Exception {
        mvc.perform(MockMvcRequestBuilders.post("/demo")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(new ObjectMapper().writeValueAsString(Demo.builder().name("create").data("data").build()))
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());

    }

    @Test
    public void update() throws Exception {
        mvc.perform(MockMvcRequestBuilders.put("/demo")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(new ObjectMapper().writeValueAsString(Demo.builder().name("update").data("data").build()))
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());

    }

    @Test
    public void delete() throws Exception {
        mvc.perform(MockMvcRequestBuilders.delete("/demo/{id}", "1")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());

    }

    @Test
    public void get() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/demo/{id}", "1")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .header("header", "header-value")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());

    }

    @Test
    public void list() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/demos")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());

    }

    @Test
    public void upload() throws Exception {
        mvc.perform(MockMvcRequestBuilders.multipart("/demo/upload").file(new MockMultipartFile("file", "test.txt", ",multipart/form-data", "upload test".getBytes()))
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());

    }
}

在啟動(dòng)日志中也可以看到Restful接口已經(jīng)暴露成功。

后語

關(guān)于這個(gè)框架的介紹,后續(xù)詳細(xì)的給大家進(jìn)行介紹。文中所涉及到的代碼也在Git中:spring-cloud-feign-proxy-sample

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/72096.html

相關(guān)文章

  • springcloud框架的簡單搭建(消費(fèi)服務(wù)基于feign

    摘要:不過,我們搭建好框架就是為了消費(fèi)它使用它,那么這篇文章就來看看如何去消費(fèi)使用我們之前搭建起來的服務(wù)吧首先本文是基于上一篇文章進(jìn)行的。代碼如下啟動(dòng)程序,多次訪問,瀏覽器顯示內(nèi)容為至此我們這個(gè)服務(wù)消費(fèi)的框架就搭建完畢了。。。 上一篇文章主要介紹了如何搭建一個(gè)簡單的springcloud框架。不過,我們搭建好框架就是為了消費(fèi)它使用它,那么這篇文章就來看看如何去消費(fèi)使用我們之前搭建起來的服務(wù)吧...

    xiguadada 評(píng)論0 收藏0
  • 史上最簡單的SpringCloud教程 | 第二篇: 服務(wù)消費(fèi)者(rest+ribbon)

    摘要:在服務(wù)架構(gòu)中,業(yè)務(wù)都會(huì)被拆分成一個(gè)獨(dú)立的服務(wù),服務(wù)與服務(wù)的通訊是基于的。配置文件如下在工程的啟動(dòng)類中通過向服務(wù)中心注冊并且注冊了一個(gè)通過注冊表明,這個(gè)是負(fù)載均衡的。 轉(zhuǎn)載請標(biāo)明出處: http://blog.csdn.net/forezp/a...本文出自方志朋的博客 在上一篇文章,講了服務(wù)的注冊和發(fā)現(xiàn)。在服務(wù)架構(gòu)中,業(yè)務(wù)都會(huì)被拆分成一個(gè)獨(dú)立的服務(wù),服務(wù)與服務(wù)的通訊是基于http re...

    dreamans 評(píng)論0 收藏0
  • springCloud學(xué)習(xí)2(服務(wù)發(fā)現(xiàn))

    摘要:服務(wù)消費(fèi)者可以使用多種模型來發(fā)現(xiàn)服務(wù)??蛻舳藢⒍ㄆ谂c服務(wù)發(fā)現(xiàn)層進(jìn)行通信,并刷新服務(wù)實(shí)例的緩存。為了達(dá)成目的,我們將要學(xué)習(xí)使用個(gè)不同的客戶端庫,服務(wù)消費(fèi)者可以使用它們來和進(jìn)行交互。 本篇代碼存放于:github 一、服務(wù)發(fā)現(xiàn)架構(gòu) ??服務(wù)發(fā)現(xiàn)架構(gòu)通常具有下面 4 個(gè)概念: 服務(wù)注冊:服務(wù)如何使用服務(wù)發(fā)現(xiàn)代理進(jìn)行注冊? 服務(wù)地址的客戶端查找:服務(wù)客戶端查找服務(wù)信息的方法是什么? 信息共享...

    史占廣 評(píng)論0 收藏0
  • SpringCloud學(xué)習(xí)(2)

    摘要:此為的結(jié)構(gòu)圖上篇已注冊了,的服務(wù),接下來用,實(shí)現(xiàn)負(fù)載均衡和的簡單客戶端,讓消費(fèi)者調(diào)用服務(wù)。是發(fā)布的云中間層服務(wù)開源項(xiàng)目,其主要功能是提供客戶側(cè)軟件負(fù)載均衡算法,將的中間層服務(wù)連接在一起。對選定的負(fù)載均衡策略機(jī)上重試機(jī)制。 ??????????上篇已經(jīng)搭建好基礎(chǔ)demo,接下來繼續(xù)構(gòu)建項(xiàng)目并對spring cloud組件介紹描述。 showImg(https://segmentfault...

    wenzi 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<