话不多说上代码 注解代码

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Import(FeignAnnotationUpdateRegistrar.class)

public @interface AEnableUpdateFeignRegistrar {

/**

* 需要修改 扫描的包,默认会使用当前类上面的EnableFeignClients里头的包

* @return

*/

String[] value() default {"net","com"};

}

反射修改类的代码

@Slf4j

public class FeignAnnotationUpdateRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {

private ResourceLoader resourceLoader;

private Environment environment;

private final Map map = MapUtil.builder("scrm-component-server", "scrm-comonent-pro")

.put("scrm-user", "tcloud-user-pro").put("scrm-crm-customer", "tcloud-customer-pro")

// todo 这里添加需要替换的微服务名和网关对应的负载均衡名(也可动态修改为url,需要改动点代码,找到使用这个map的地方修改下)

.put("scrm-paas-common", "http://*******")

.map();

@Override

public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {

ClassPathScanningCandidateComponentProvider scanner = this.getScanner();

scanner.setResourceLoader(this.resourceLoader);

scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class));

Set basePackages = this.getBasePackages(metadata);

Iterator var8 = basePackages.iterator();

LinkedHashSet candidateComponents = new LinkedHashSet();

while (var8.hasNext()) {

String basePackage = (String) var8.next();

candidateComponents.addAll(scanner.findCandidateComponents(basePackage));

}

for (BeanDefinition definition : candidateComponents) {

try {

if (definition instanceof AnnotatedBeanDefinition) {

AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition)definition;

AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();

MergedAnnotations annotations = annotationMetadata.getAnnotations();

Class feignClass = Class.forName(beanDefinition.getBeanClassName());

FeignClient feignClient = feignClass.getAnnotation(FeignClient.class);

Object value = feignClient.value();

String url = this.map.get(value);

if (url != null) {

InvocationHandler h = Proxy.getInvocationHandler(feignClient);

// 获取 AnnotationInvocationHandler 的 memberValues 字段

Field hField = h.getClass().getDeclaredField("memberValues");

// 因为这个字段事 private final 修饰,所以要打开权限

hField.setAccessible(true);

// 获取 memberValues

Map memberValues = (Map) hField.get(h);

// 修改 value 属性值

memberValues.put("url",url);

}

for (MergedAnnotation annotation : annotations) {

Class aClass = annotation.getType();

if (aClass.isAssignableFrom(FeignClient.class)) {

Class annotationClass = annotation.getClass();

Field rootAttributes = annotationClass.getDeclaredField("rootAttributes");

rootAttributes.setAccessible(true);

Object attributes = rootAttributes.get(annotation);

if (attributes instanceof Map) {

Map map = (Map) attributes;

Object value = map.get("value");

String url = this.map.get(value);

if (url != null) {

// 这里就是替换feignClient注解里头的url,后面的值可以自定义填写

map.put("url", "https://preapiconsole.71360.com/api/app/" + url);

}

}

}

}

}

} catch (Exception e) {

log.error("反射修改feign的url失败", e);

}

}

}

private ClassPathScanningCandidateComponentProvider getScanner() {

return new ClassPathScanningCandidateComponentProvider(false, this.environment) {

protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {

boolean isCandidate = false;

if (beanDefinition.getMetadata().isIndependent() && !beanDefinition.getMetadata().isAnnotation()) {

isCandidate = true;

}

return isCandidate;

}

};

}

protected Set getBasePackages(AnnotationMetadata importingClassMetadata) {

Map attributes = importingClassMetadata.getAnnotationAttributes(EnableFeignClients.class.getCanonicalName());

Set basePackages = new HashSet();

String[] var4 = (String[]) ((String[]) attributes.get("value"));

int var5 = var4.length;

int var6;

String pkg;

for (var6 = 0; var6 < var5; ++var6) {

pkg = var4[var6];

if (StringUtils.hasText(pkg)) {

basePackages.add(pkg);

}

}

var4 = (String[]) ((String[]) attributes.get("basePackages"));

var5 = var4.length;

for (var6 = 0; var6 < var5; ++var6) {

pkg = var4[var6];

if (StringUtils.hasText(pkg)) {

basePackages.add(pkg);

}

}

Class[] var8 = (Class[]) ((Class[]) attributes.get("basePackageClasses"));

var5 = var8.length;

for (var6 = 0; var6 < var5; ++var6) {

Class clazz = var8[var6];

basePackages.add(ClassUtils.getPackageName(clazz));

}

if (basePackages.isEmpty()) {

basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));

}

return basePackages;

}

public void setResourceLoader(ResourceLoader resourceLoader) {

this.resourceLoader = resourceLoader;

}

public void setEnvironment(Environment environment) {

this.environment = environment;

}

}

特别需要注意的事项: EnableUpdateFeignRegistrar 这个注解必须要放到EnableFeignClients前头 如下

6月29 更新,可能会有从其它地方引入的feign导致修改不到 比如在其它的配置类中加EnableFeignClients,或者用Import 所以在注解中加了value,value中的包都会被扫描然后反射修改注解的值,从根源上解决问题

精彩内容

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。