0
点赞
收藏
分享

微信扫一扫

Feign加载异常:Requested bean is currently in creation: Is there an unresolvable circular reference

现象

        在使用EnableFeignClients指定加载包时,启动出现下面的异常。

ERROR 56739 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 
'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': 

Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is 
org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'webConfigurerAdapter':

Unsatisfied dependency expressed through field 'cipherAuthInterceptor'; 
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:

Error creating bean with name 'cipherAuthInterceptor': 
Unsatisfied dependency expressed through field 'authService';

nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:
 Error creating bean with name 'mvcResourceUrlProvider': 
Requested bean is currently in creation: Is there an unresolvable circular reference?

原因分析

本例相关代码

  • 启动类
@SpringBootApplication
@EnableFeignClients({"com.lizz.test.api"})
public class LizzApplication {
    public static void main(String[] args) {
        SpringApplication.run(LizzApplication.class, args);
    }
}
package com.lizz.test.api;
@FeignClient(name = "LIZZ-TEST-SERVER")
public interface AuthService {
    /**
     * 验证权限URI
     *
     * @param token
     * @param uri
     * @return String
     */
    @PostMapping("/auth")
    Boolean checkUri(@RequestParam(name = "token") String token,
                    @RequestParam(name = "uri") String uri);
}
  • 配置类添加拦截器
@Configuration
public class WebConfigurerAdapter implements WebMvcConfigurer {

    @Autowired
    private AuthInterceptor authInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //增加自定义拦截方法
        registry.addInterceptor(authInterceptor)
                .addPathPatterns("/**"); //拦截的api路径
    }
}
  • 拦截器
@Slf4j
@Configuration
public class AuthInterceptor implements HandlerInterceptor {
    @Autowired
    private AuthService authService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        if (authService.checkUri("xxx","xxx")) {
            return true;
        } else {
            return false;
        }
    }
}
  • 其他Feign client代码
package com.lizz.test.api;
@FeignClient(name = "LIZZ-OTHER-SERVER")
public interface LizzOtherServer {
    /**
     * 验证权限URI
     *
     * @param token
     * @param uri
     * @return String
     */
    @PostMapping("/test")
    Boolean test();
}
  •  引用其他Feign client
@Service
public class LizzServiceImpl  {

    @Autowired
    private LizzOtherServer lizzOtherServer;

    public void test(String type, String data) {
       lizzOtherServer.test();
    }
}
  • 使用了WebMvcConfigurer添加拦截器
  • 又在HandlerInterceptor拦截器中调用了feignclient服务
  • 因此出现了循环引用的情况
  • 如果只有这一个地方加载了feignclient服务,也不会出现异常情况。
  • 由于本例中在其他service中使用了feignclinet方法,FeignClient初始化时会将所有feignclient进行初始化。
  • 导致在HandlerInterceptor加载时出现了异常。

解决办法

  • 出现类是循环引用时,通过@Lazy 延时加载的方式解决
  • 即service类中加载其他feignclinet时,不加载HandlerInterceptor中引用的类
  • 如果service中的类和HandlerInterceptor一样,都可以加上@Lazy
@Slf4j
@Configuration
public class AuthInterceptor implements HandlerInterceptor {
    @Autowired
    @Lazy
    private AuthService authService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        if (authService.checkUri("xxx","xxx")) {
            return true;
        } else {
            return false;
        }
    }
}

举报

相关推荐

0 条评论