Вещи, о которых вы не знаете --- функция наследования притворства SringCloud

Spring Cloud

предисловие

Говоря о притворстве SpringChoud, все использовали его и говорили, что это хорошо. Feign — это декларативный шаблонный HTTP-клиент, разработанный Netflix. Для наших микросервисов удобнее использовать feign для вызовов API между микросервисами. В этой статье сначала рассказывается о традиционном способе вызова feign, а затем вводятся характеристики наследования нашего ключа feign. Функция наследования feign имеет много преимуществ.Она может выполнять унифицированное управление параметрами и методами.Одна модификация, feign и конкретный контроллер меняются. Тем не менее, есть много преимуществ.

Реализация традиционного притворства

Как реализован традиционный симулянт?Сначала мы создали контроллер через springmvc и реализовали наш код в контроллере. В это время другая микрослужба хочет напрямую вызвать запрос, тогда вызываемая микрослужба может объявить фиктивного клиента и предоставить себя методу, вызываемому извне, сопоставление пути requestMapper метода, предоставленного фикцией, и удержание в контроллере Постоянно доступный .

Кодовая реализация традиционной симуляции

Начнем с написания традиционного контроллера. Наша цель очень проста, этот контроллер возвращает 123.

@RestController
public class DemoController {

    @PostMapping("/demo/list")
    public String demo(
            @RequestBody DemoFeignQueryVO demoFeignQueryVO){
      return "123";
    }
}

С контроллером напишем feign. Код feign очень прост, главное, чтобы значение feignClint гарантированно было значением микросервиса, который мы хотим вызвать, и тогда значение postMapping в нем можно назвать таким же, как и у контроллера выше.

@FeignClient(value = "user-system")
@Component
public interface IDemoFeign {

    @PostMapping("/demo/list")
    public String demo(
            @RequestBody DemoFeignQueryVO demoFeignQueryVO);

}

Недостатки традиционной симуляции

Судя по приведенному выше коду, какие минусы, например, если я хочу изменить параметры контроллера, то мне нужно изменить два места, одно — это моя собственная реализация контроллера, а другое — интерфейс feign. Если вы забудете изменить его, произойдет неизвестная ошибка. Что делать, если отображение пути контроллера изменено. Точно так же необходимо изменить два местоположения. Это недостаток традиционной формы.

Особенности наследования притворства

Если мы используем функцию наследования feign, описанной выше ситуации не произойдет, функция наследования означает, что мы получаем общий интерфейс, размещаем наши аннотации requestMapping на интерфейсе и указываем параметры нашего метода. Затем реализуйте этот интерфейс через контроллер. Контроллер может реализовывать один за другим методы интерфейса. Затем для нашего фиктивного интерфейса мы напрямую наследуем общий интерфейс. Таким образом, симуляционный интерфейс и метод контроллера полностью совместимы.Когда требуется модификация, нет необходимости изменять два места вместе, и общий интерфейс можно изменить напрямую.

Кодовая реализация функции наследования feign

Мы перепишем код вышеприведенной традиционной схемы и сможем увидеть преимущества в сравнении. Сначала объявите общий интерфейс. Здесь мы пишем все методы, которые хотим предоставить внешнему миру.

public interface DemoInterface {
 
    @PostMapping("/demo/list")
    public String demo(
            @RequestBody DemoFeignQueryVO demoFeignQueryVO);
    
}

С интерфейсом наш контроллер непосредственно реализует этот интерфейс.

@RestController
public class DemoController implements DemoInterface {

    @Override
    public String demo(
            @RequestBody DemoFeignQueryVO demoFeignQueryVO){
      return "123";
    }
}

На данный момент мы видим, что контроллеру не нужно заботиться о сопоставлении путей. А по параметрам, если модифицировать интерфейс, контроллер неизбежно выдаст ошибку, компиляция не пройдет, и вы не пропустите изменение. Далее реализуем нашу симуляцию, симулировать чрезвычайно просто, если вы наследуете общий интерфейс.

@FeignClient(value = "user-system")
public interface DemoFeign extends DemoInterface  {
}

Посмотрите, очень ли это удобно. Притворщику и контроллеру не нужно заботиться о пути, общий порт гарантирует, что путь должен быть непротиворечивым, а проверка параметров интерфейса также гарантирует, что параметры не вызовут проблем.

Проблема с загрузкой requestMapping, вызванная функцией имитации наследования

В нашем вышеупомянутом решении, если requestMapping используется только для аннотаций, этой проблемы не возникнет. Но если requestMapping находится в классе контроллера, возникает проблема. Давайте сначала рассмотрим логику загрузки SpringMvc requestMapping в контейнер.

@Override
protected boolean isHandler(Class<?> beanType) {
    return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
            AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}

Это основа суждения для обработки сопоставления запросов. Из реализации видно, что пока сканируемый класс содержит аннотацию @Controller или @RequestMapping, он будет загружен SpringMVC, затем контроллер реализует интерфейс с отображением запроса. feignClient также наследует интерфейс, поэтому у него также есть requestMapping. Два идентичных requestMapping неизбежно будут конфликтовать. Итак, какова наша цель. Нормальная загрузка контроллера, feignClient не должен загружаться. Мы повторно модифицируем класс конфигурации feign.

@Configuration
@ConditionalOnClass({Feign.class})
public class FeignConfiguration {
    @Bean
    public WebMvcRegistrations feignWebRegistrations() {
        return new WebMvcRegistrationsAdapter() {
            @Override
            public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
                return new FeignRequestMappingHandlerMapping();
            }
        };
    }
    private static class FeignRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
        @Override
        protected boolean isHandler(Class<?> beanType) {
            return super.isHandler(beanType) &&
                    !AnnotatedElementUtils.hasAnnotation(beanType, FeignClient.class);
        }
    }
}

Мы сделали исключение в приведенном выше коде и не загружаем его с помощью feignClint. На данный момент здесь нет скрытой ямы функции наследования притворства, и вы можете использовать ее с уверенностью.

Суммировать

Функция наследования feign — очень удобный способ, который действительно сокращает объем написания кода и обеспечивает согласованность сопоставления путей и параметров. Очень полезно. В тексте есть неизбежные недостатки, и критика и исправления приветствуются.