|
|
|
|
@ -49,11 +49,11 @@ public class FeignEagerLoadContextInitializer implements ApplicationListener<App
|
|
|
|
|
|
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(FeignEagerLoadContextInitializer.class);
|
|
|
|
|
|
|
|
|
|
private ApplicationContext applicationContext;
|
|
|
|
|
private final ApplicationContext applicationContext;
|
|
|
|
|
|
|
|
|
|
private LoadBalancerClientFactory loadBalancerClientFactory;
|
|
|
|
|
private final LoadBalancerClientFactory loadBalancerClientFactory;
|
|
|
|
|
|
|
|
|
|
private LoadBalancerEagerLoadProperties loadBalancerEagerLoadProperties;
|
|
|
|
|
private final LoadBalancerEagerLoadProperties loadBalancerEagerLoadProperties;
|
|
|
|
|
|
|
|
|
|
public FeignEagerLoadContextInitializer(ApplicationContext applicationContext,
|
|
|
|
|
LoadBalancerClientFactory loadBalancerClientFactory,
|
|
|
|
|
@ -63,16 +63,46 @@ public class FeignEagerLoadContextInitializer implements ApplicationListener<App
|
|
|
|
|
this.loadBalancerEagerLoadProperties = loadBalancerEagerLoadProperties;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Target.HardCodedTarget<?> getHardCodedTarget(Object proxy) {
|
|
|
|
|
try {
|
|
|
|
|
int count = 0;
|
|
|
|
|
Object invocationHandler = proxy;
|
|
|
|
|
// Avoid infinite loop
|
|
|
|
|
while (count++ < 100) {
|
|
|
|
|
invocationHandler = Proxy.getInvocationHandler(invocationHandler);
|
|
|
|
|
if (invocationHandler instanceof AopProxy) {
|
|
|
|
|
invocationHandler = JdkDynamicAopProxyUtils.getTarget(invocationHandler);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (Field field : invocationHandler.getClass().getDeclaredFields()) {
|
|
|
|
|
field.setAccessible(true);
|
|
|
|
|
Object fieldValue = field.get(invocationHandler);
|
|
|
|
|
if (fieldValue instanceof Target.HardCodedTarget) {
|
|
|
|
|
return (Target.HardCodedTarget<?>) fieldValue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e) {
|
|
|
|
|
if (LOG.isDebugEnabled()) {
|
|
|
|
|
LOG.debug("proxy:{}, getTarget failed.", proxy, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
|
|
|
|
|
LOG.info("feign eager-load start");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get services that are already warmed by LoadBalancerEagerContextInitializer
|
|
|
|
|
Set<String> skipServices = getLoadBalancerEagerLoadServices();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set to track already warmed services
|
|
|
|
|
Set<String> warmedServices = new HashSet<>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Warm up FeignClient services
|
|
|
|
|
for (Object bean : applicationContext.getBeansWithAnnotation(FeignClient.class).values()) {
|
|
|
|
|
try {
|
|
|
|
|
@ -95,7 +125,7 @@ public class FeignEagerLoadContextInitializer implements ApplicationListener<App
|
|
|
|
|
LOG.debug("[{}] skip eager-load, already configured in LoadBalancerEagerLoadProperties.clients", serviceName);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Skip if already warmed in this round
|
|
|
|
|
if (warmedServices.contains(serviceName)) {
|
|
|
|
|
LOG.debug("[{}] already warmed, skip.", serviceName);
|
|
|
|
|
@ -124,41 +154,11 @@ public class FeignEagerLoadContextInitializer implements ApplicationListener<App
|
|
|
|
|
*/
|
|
|
|
|
private Set<String> getLoadBalancerEagerLoadServices() {
|
|
|
|
|
Set<String> services = new HashSet<>();
|
|
|
|
|
if (loadBalancerEagerLoadProperties != null
|
|
|
|
|
if (loadBalancerEagerLoadProperties != null
|
|
|
|
|
&& loadBalancerEagerLoadProperties.isEnabled()
|
|
|
|
|
&& loadBalancerEagerLoadProperties.getClients() != null) {
|
|
|
|
|
services.addAll(loadBalancerEagerLoadProperties.getClients());
|
|
|
|
|
}
|
|
|
|
|
return services;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Target.HardCodedTarget<?> getHardCodedTarget(Object proxy) {
|
|
|
|
|
try {
|
|
|
|
|
int count = 0;
|
|
|
|
|
Object invocationHandler = proxy;
|
|
|
|
|
// Avoid infinite loop
|
|
|
|
|
while (count++ < 100) {
|
|
|
|
|
invocationHandler = Proxy.getInvocationHandler(invocationHandler);
|
|
|
|
|
if (invocationHandler instanceof AopProxy) {
|
|
|
|
|
invocationHandler = JdkDynamicAopProxyUtils.getTarget(invocationHandler);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (Field field : invocationHandler.getClass().getDeclaredFields()) {
|
|
|
|
|
field.setAccessible(true);
|
|
|
|
|
Object fieldValue = field.get(invocationHandler);
|
|
|
|
|
if (fieldValue instanceof Target.HardCodedTarget) {
|
|
|
|
|
return (Target.HardCodedTarget<?>) fieldValue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e) {
|
|
|
|
|
if (LOG.isDebugEnabled()) {
|
|
|
|
|
LOG.debug("proxy:{}, getTarget failed.", proxy, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|