1、前提:
将该静态方法中获取userName的方法用feign方法实现
注意:
由于 AuthDomainCenterFeign 是一个接口,并且使用了 @FeignClient 注解,Spring Cloud Feign 会自动为您创建这个接口的一个实现类实例,并将其作为一个Bean注册到Spring应用上下文中。这意味着您可以像使用其他Spring管理的Bean一样使用 AuthDomainCenterFeign。
然而,由于您需要在静态方法中使用 AuthDomainCenterFeign,我们不能直接在静态方法里@Autowired注入这个Feign客户端。
解决这个问题的一种方法是通过非静态的配置类来注入Feign客户端,然后通过这个配置类来提供静态访问Feign客户端的方法。
2、代码实例:
//原方法
public static String getUserName() {
Object value = get(Constant.HEADER_CURRENT_USER_NAME);
String userName = returnObjectValue(value);
if (StringUtils.isNotEmpty(userName)) {
try {
userName = URLDecoder.decode(userName, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
//上面方法使用这个feign方法查询userName
@Component
@FeignClient(name = "AuthFeign", url = "${authCenter.baseUrl}",configuration = AuthenticationInterceptor.class)
public interface AuthFeign{
/**
* 3.2 查询用户基本信息
* @param dto dto
* @return Result<UserOrgInfoDto>
*/
@PostMapping("${authCenter.userInfo}")
R<UserDetailVo> getUserInfo(@RequestBody UserInfoQueryDto dto);
}
3、解决方法:
由于 `getUserName` 需要保持为静态方法,并且您无法直接在静态字段上使用 `@Autowired` 进行自动注入,您可以采用以下步骤来实现:
1. **创建非静态的配置类**:这个类将用于Spring的依赖注入。
2. **在配置类中初始化静态变量**:通过构造函数或初始化块来初始化静态变量。
3. **提供静态方法访问Feign客户端和RedisUtil**。
代码实现:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ServiceLocator {
// 静态变量,用于存储依赖
private static RedisUtil redisUtil;
private static AuthFeign feignClient;
// 构造函数注入
@Autowired
public ServiceLocator(RedisUtil redisUtil, AuthFeign feignClient) {
ServiceLocator.redisUtil = redisUtil;
ServiceLocator.feignClient = feignClient;
}
// 提供静态方法访问静态变量
public static RedisUtil getRedisUtil() {
return redisUtil;
}
public static AuthFeign getFeignClient() {
return feignClient;
}
}
然后,您可以在 getUserName
静态方法中使用 ServiceLocator
来访问这些依赖项:
public class UserServiceImpl {
public static String getUserName() {
// 从 ServiceLocator 获取依赖项
Object value = get(Constant.HEADER_CURRENT_USER);
String userId = returnObjectValue(value);
String userName = ServiceLocator.getRedisUtil().get(userId);
if (StringUtils.isEmpty(userName)) {
ServiceLocator.getRedisUtil().delete(userId);
UserInfoQueryDto dto = new UserInfoQueryDto();
dto.setUserCode(userId);
R<UserDetailVo> result = ServiceLocator.getFeignClient().getUserInfo(dto);
if (result != null && result.getCode() == 200) { // 假设getCode返回的是HTTP状态码
UserDetailVo userDetailVo = result.getData();
if (userDetailVo != null) {
userName = userDetailVo.getUserName();
ServiceLocator.getRedisUtil().set(userId, userName);
}
}
}
return userName;
}
}
请注意,`ServiceLocator` 是一个单例模式的类,它在Spring容器启动时被创建和初始化。由于 `ServiceLocator` 是一个Spring组件,它将自动接收Spring容器注入的依赖项。
此外,您需要确保 `ServiceLocator` 类被Spring容器管理,通常是通过使用 `@Component` 注解来实现。这样,Spring容器就可以自动处理依赖注入,并在容器启动时初始化静态变量。
最后,由于 `getUserName` 是静态方法,它将直接调用 `ServiceLocator` 中的静态方法来访问所需的依赖项。这种方法允许您保持 `getUserName` 为静态方法,同时满足Spring依赖注入的要求。