Title

maven项目下feign公共模块

  • 导包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>sc-login</artifactId>
        <groupId>org.login</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.login</groupId>
    <artifactId>login-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-openfeign-core</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>none</mainClass>     <!-- 取消查找本项目下的Main方法:为了解决Unable to find main class的问题 -->
                    <classifier>execute</classifier>    <!-- 为了解决依赖模块找不到此模块中的类或属性 -->
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
  • 目录

api目录

login-common 主要存放 feign 接口,提给给其他微服务调用
login-server 主要是存放业务代码

  • 实现

feign 接口

package com.zl.common.api;

import com.zl.common.api.fallback.RoleClientFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Primary;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.zl.server.domain.user.model.entity.User;

/**
 * @author z
 */
@Primary
@FeignClient(name = "login", primary = false, qualifier = "loginClient", fallback = LoginClientFallback.class)
public interface LoginClient {
    /**
     * 获取用户信息
     *
     * @param userId 用户id
     * @return 用户信息
     */
    @GetMapping("/user/getUserInfo")
    User getUserInfo(@RequestParam String userId);
}

@FeignClient 中的 name,value 属性值为application.properties的 spring.application.name=login 的值
@GetMapping("/user/getUserInfo") 属性值为controller路径加上接口路径

feign接口熔断

package com.zl.common.api.fallback;

import com.zl.common.api.LoginClient;
import org.springframework.stereotype.Component;
import com.zl.server.domain.user.model.entity.User;

/**
 * LoginClient fallback
 *
 * @author z
 * @date 2022-04-02 11:30
 */
@Component
public class LoginClientFallback implements LoginClient {

    @Override
    public User getUserInfo(String userId) {
        return null;
    }
}

在熔断上面加 @Component 注解,才能使 LoginClientFallback 生效

feign接口实现

package com.zl.server.domain.user.web.api;

import com.zl.common.api.LoginClient;
import com.zl.server.domain.user.service.ISysUserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;
import com.zl.server.domain.user.model.entity.User;
import javax.annotation.Resource;


/**
 * 用户 api 实现feign接口,并调用返回结果
 *
 * @author z
 * @date 2022-04-02 11:37
 */
@RestController
@ApiIgnore
public class LoginClientController implements LoginClient {
    /**
     * 用户 service
     */
    @Resource
    private ISysUserService iSysUserService;

    /**
     * 获取用户信息
     *
     * @param userId 用户id
     * @return 用户信息
     */
    @GetMapping("/user/getUserInfo")
    @Override
    public User getUserInfo(@RequestParam String userId) {
        User list = iSysUserService.getUserInfo(userId);
        return User;
    }
}

需要controller实现feign接口,与前端交互的controller分开便于管理
在启动类LoginApplication中加入@EnableFeignClients(basePackages = {"com.zl.**.api"})注解使feign接口生效

最后,将这个公共的feign模块包引入到其他的模块中就可以调用了

问题:

  • application.properties 配置了 server.servlet.context-path为/user,导致feign接口调用失败

解决:

在 @FeignClient 注解里使用 path 属性指定请求前缀,@FeignClient(name = "login", path="user")

  • 出现:NoUniqueBeanDefinitionException: No qualifying bean of type 'com.zl.api.xxxClient' available

解决:

@Resource(name = "loginClient")
private LoginClient loginClient;

@Qualifier注解,使用场景跟上面的primary关系很淡,一般场景直接@Autowired直接注入就可以了。
如果我们的Feign Client有fallback实现,默认@FeignClient注解的primary=true, 意味着我们使用@Autowired注入是没有问题的,会优先注入你的FeignClient。
如果你把primary设置成false了,直接用@Autowired注入的地方就会报错,不知道要注入哪个对象。
解决方案很明显,你可以将primary设置成true即可,如果由于某些特殊原因,你必须得去掉primary=true的设置,这种情况下我们怎么进行注入,我们可以配置一个qualifier,然后使用@Qualifier注解进行注入

posted @ 2022-04-02 15:53  快乐小洋人  阅读(702)  评论(0编辑  收藏  举报