SpringCloud:多模块下Feign的使用,@Autowired注入问题以及JSON问题

Feign简介

Feign是一个声明式WebService客户端.使用Feign能让编写WebService客户端更加简单,它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解.Feign也支持可拔插式的编码器和解码器.Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters.Feign可以与Eureka和Ribbon组合使用以支持负载均衡.

Feign的使用

  1. 服务暴露api模块消费者模块的pom中均加入依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
  1. 在服务暴露api模块中创建Client接口类并声明注解@FeignClient(name = “XXXX”),
    接口类中的方法书写要注意:①@RequestMapping(“XXX/XXX”)代表要访问的服务的地址;②方法返回值类型一定要和客户端方法的返回值保持一致,例如客户端Controller的list方法返回值是ResultVO,那么api方法的返回值也必须是ResultVO(也可以只写ResultVO),否则会发生JSON无法反序列化问题(Error while extracting response for type [com.xmtx.XXXX] and content type [application/json].Can not deserialize instance of java.util.ArrayList out of START_OBJECT token)
  2. 在消费者模块的主启动类Application中声明@EnableFeignClients(basePackages = “com.XXXX”)
    注意:在多模块下一定要加上(basePackages = “com.XXXX”),否则会导致自动注入失败问题
  3. 多模块下需要把服务暴露api模块pom进消费者模块的依赖中。如3的注意事项:在多模块下@EnableFeignClients一定要加上(basePackages = “com.XXXX”),否则就是pom进来也会导致无法自动注入
  4. 在消费者端@Autowired自动注入暴露api接口类,调用类方法实现对服务的调用。

@Autowired自动注入失败问题

在自动注入Feign的客户端api接口类时,发现标红,显示

Could not autowire. No beans of 'XXXClient' type found.

网上查,很多答案说改IDE提示,但这种做法的前提是程序编译不要出错,但我此时编译却会出现以下问题:

Consider defining a bean of type 'com.XXX.XXXClient' in your configuration.

**说明这不是IDE提示问题,是真的就找不到该bean。。。**当时就纳闷了,明明在pom中把api模块加入依赖了,该client类也能import进来,怎么就找不到该bean,没法自动注入呢

TODO:在POM中加入模块依赖的作用,为啥不能自动注入???
TODO:@EnableFeignClients注解中basePackages = "com.XXXX"的作用

当时也没想feign注解问题(第一次搞。。),觉得是不是没扫描到,我就用@ComponentScan(basePackages=“com.XXXX”)去扫描,但没用,即使类的前缀包一样。。。。。
改basePackages="com.XXXX.XXXClient"该错误是没了,但又发现,扫描不到当前Controller类了。。。。
再改basePackages={“com.XXXX.XXXClient”,“com.XXX.XXXController”},还是没用,找不到client的bean。

最终,才终于发现应该在@EnableFeignClients上加上(basePackages = “com.XXXX”),其中"com.XXXX"是client类和当前类的共同前缀包。

feign下的JSON序列化和反序列化问题

feign是使用http进行传输的,而http传输需要进行序列化和反序列化,在feign的客户端和服务接口api之间传输时,一定注意方法返回值类型一定要和客户端方法的返回值保持一致。

例如:客户端Controller的list方法返回值是ResultVO,那么api方法的返回值也必须是ResultVO(也可以只写ResultVO),否则会发生JSON无法反序列化问题(Error while extracting response for type [com.xmtx.XXXX] and content type [application/json].Can not deserialize instance of java.util.ArrayList out of START_OBJECT token)

你可能感兴趣的:(Spring,Cloud)