Spring AOP не перехватывает вызовы Feign.Client - PullRequest
0 голосов
/ 21 июня 2019

Я пытаюсь использовать Spring AOP для перехвата Feign.Client вызовов и регистрации запросов и ответов на моем сервере Splunk.Все методы в моем пакете проекта перехвачены, как я и ожидал, но Feign.Client нет.

Это мой класс AOP:

@Component
@Aspect
public class MyAspect {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Pointcut("execution(* com.example.demo.*.*(..))")
    public void pointCutDemo(){}

    @Pointcut("execution(* feign.Client+.*(..))")
    public void pointCutFeign(){}

    @Around("pointCutDemo()")
    public void myAroundDemo(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.info("calling joinpoint "+joinPoint.getSignature().getName());
        joinPoint.proceed();
    }

    @Around("pointCutFeign()")
    public void myAroundFeign(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.info("calling feign joinpoint "+joinPoint.getSignature().getName());
        joinPoint.proceed();
    }
}

Метод myAroundDemo вызывается несколько раз,как я и ожидал, но myAroundFeign никогда не вызывается.

У меня есть простой контроллер, который вызывает мой интерфейс (Feign API), это контроллер:

@RestController
public class Controller {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ExternalAPI externalAPI;

    @GetMapping
    public String get(){
        logger.info("calling get method");
        logger.info(String.valueOf(externalAPI.listUsers()));
        return "I'm here";
    }
}

А это мой интерфейс Feign:

@FeignClient(url = "http://localhost:3000", name = "feign", configuration = FeignConfig.class)
public interface ExternalAPI {
    @GetMapping(value = "/menu")
    String listUsers();
}

Ответы [ 4 ]

1 голос
/ 21 июня 2019

@ kriegaex правильно, и я не могу применить AOP в компонентах, отличных от Spring.Но я предпочитаю не использовать чистый AspectJ, поэтому я исправил другое решение.Вот мои шаги для решения проблемы:

1) Включение ленты Spring Cloud Я получил класс LoadBalancerFeignClient, управляемый Spring, который реализует feign.Client, поэтому я добавил зависимость в pom.xml и изменил свое приложение.yml.

application.yml

myfeign:
  ribbon:
    listOfServers: localhost:3000

pom.xml

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

2) In MyAspect класс, который я перехватил LoadBalancerFeignClient класс:

@Pointcut("execution(* org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient.execute(..))")
public void pointCutFeign(){}

@Around("pointCutFeign()")
public Object myAroundFeign(ProceedingJoinPoint joinPoint) throws Throwable {
    if (joinPoint.getArgs().length > 0) {
        Request request = (Request) joinPoint.getArgs()[0];
        logger.info("REQUEST >>>>>>>>>>>>");
        logger.info("URL = "+request.url());
        logger.info("METHOD = "+request.httpMethod().name());
        logger.info("BODY = "+request.requestBody().asString());
        logger.info("HEADERS = "+request.headers().toString());
    }

    Response response = (Response) joinPoint.proceed();

    logger.info("RESPONSE <<<<<<<<<<<<<<");
    logger.info("STATUS = "+response.status());
    logger.info("HEADERS = "+response.headers().toString());
    logger.info("BODY = " + IOUtils.toString(response.body().asInputStream(), "UTF-8"));
    return response;
}

Теперь все работает очень хорошо, я получил всю необходимую информацию.

1 голос
/ 21 июня 2019

Spring AOP применяется только к компонентам Spring. Я думаю, что это не работает, потому что Feign не является компонентом Spring и, следовательно, выходит за рамки Spring AOP. Если вам нужно применить аспекты к классам, отличным от Spring, просто используйте полный AspectJ. В руководстве Spring объясняется, как настроить его через LTW (время загрузки) .

0 голосов
/ 18 июля 2019

Feign имеет встроенную систему регистрации, которую вы можете использовать без AOP.Если вы создадите экземпляр feign.Logger и зарегистрируете его, он запишет запрос, ответ и заголовки.

@Bean
public feign.Logger logger() {
    /* requires feign-slf4j */
    return new Slf4jLogger();
}

Logger экземпляры предоставляют следующие функции:

  • Запросы регистрируются перед отправкой клиенту.
  • Ответы регистрируются независимо от статуса после получения.
  • Повторные попытки регистрируются, если они инициированы.

Это может быть лучшим решением, если ведение журнала - это все, что вам нужно.

0 голосов
/ 11 июля 2019

Я тоже сталкиваюсь с этим вопросом. но я не могу перехватить класс LoadBalancerFeignClient. я использую тот же код для тестирования, но он не работает. введите описание изображения здесь

когда я отлаживаю функцию, я нахожу (эту) точку на TraceLoadBalanceFeignClient. Подкласс LoadBalancerFeignClient. Наконец, я нахожу, когда использую sleuth. feign клиент будет создан feignbuilder Sleuth. Pointcut будет недействительным

...