Reputation:
We are using Open Feign in our application, which is running on Spring Boot 2.0.6 and Spring Cloud Finchley.SR2.
We need all of the Feign Clients to add a token from the security context in the header of every call, so we created a configuration, which produces a global Interceptor for all clients:
@Configuration
@Import({FeignClientsConfiguration.class})
public class FeignConfig {
@Value("${a.spring.config}")
private int minTokenLifespan;
@Autowired
private OAuthContext oAuthContext;
@Autowired
private AuthManager authManager;
@Bean
public RequestInterceptor myCustomInterceptor() {
return new CustomInterceptor(oAuthContext, authManager, minTokenLifespan);
}
}
The interceptor works for all Feign Clients but one. In the debugger we can see, that this special feign client (along with its the SynchronousMessageHandler) is created, before the Bean is created in the class FeignConfig
. The CustomIntercepter
is only created after the first Feign Client, all other clients are created afterward, know of the Interceptors existence and will apply it.
How can we debug this issue? Has anyone had a different problem in the past?
I can't post production code, but I would be happy to answer any question and try to post obfuscated code.
Upvotes: 6
Views: 3603
Reputation: 173
This points to a problem in creating the interceptor at the time the first client gets created.
Try putting a conditional breakpoint in org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeansOfType
on RequestInterceptor.class
. You might see that a circular dependency exists which requires the first client to be created before the FeignConfig
or CustomInterceptor
classes can be instantiated.
Consider the following example:
@Configuration
@EnableFeignClients(
clients = {
MyFirstClient.class, // will NOT have CustomInterceptor registered
MySecondClient.class // will have CustomInterceptor registered
})
public class FeignConfig {
@Autowired
private BeanDependentOnMyFirstClient beanDependentOnMyFirstClient;
@Bean
public RequestInterceptor myCustomInterceptor() {
return new CustomInterceptor();
}
}
This will result in the following circular dependency:
Since the dependency between the clients and the interceptor is weak, it will just fail silently if the dependency cannot be met.
Upvotes: 6