Commit b27ba043 by Arnaud Brunet Committed by Spencer Gibb

More robust instantiation in SpringClientFactory

SpringClientFactory returns null if the class is not aware of IClientConfig. This change catches the exception when trying the constructor with IClientConfig so classes that aren't aware of IClientConfig can be created. Fixes gh-1608
parent 3b41b5e1
......@@ -16,6 +16,8 @@
package org.springframework.cloud.netflix.ribbon;
import java.lang.reflect.Constructor;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.context.named.NamedContextFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
......@@ -80,33 +82,30 @@ public class SpringClientFactory extends NamedContextFactory<RibbonClientSpecifi
static <C> C instantiateWithConfig(AnnotationConfigApplicationContext context,
Class<C> clazz, IClientConfig config) {
C result = null;
if (IClientConfigAware.class.isAssignableFrom(clazz)) {
IClientConfigAware obj = (IClientConfigAware) BeanUtils.instantiate(clazz);
obj.initWithNiwsConfig(config);
@SuppressWarnings("unchecked")
C value = (C) obj;
result = value;
try {
Constructor<C> constructor = clazz.getConstructor(IClientConfig.class);
result = constructor.newInstance(config);
} catch (Throwable e) {
// Ignored
}
else {
try {
if (clazz.getConstructor(IClientConfig.class) != null) {
result = clazz.getConstructor(IClientConfig.class)
.newInstance(config);
}
else {
result = BeanUtils.instantiate(clazz);
}
if (result == null) {
result = BeanUtils.instantiate(clazz);
if (result instanceof IClientConfigAware) {
((IClientConfigAware) result).initWithNiwsConfig(config);
}
catch (Throwable ex) {
// NOPMD
if (context != null) {
context.getAutowireCapableBeanFactory().autowireBean(result);
}
}
if (context != null) {
context.getAutowireCapableBeanFactory().autowireBean(result);
}
return result;
}
@Override
public <C> C getInstance(String name, Class<C> type) {
C instance = super.getInstance(name, type);
if (instance != null) {
......
......@@ -23,9 +23,13 @@ import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.netflix.client.DefaultLoadBalancerRetryHandler;
import com.netflix.client.IClientConfigAware;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.niws.client.http.RestClient;
import com.sun.jersey.client.apache4.ApacheHttpClient4;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.springframework.boot.test.util.EnvironmentTestUtils.addEnvironment;
......@@ -35,6 +39,31 @@ import static org.springframework.boot.test.util.EnvironmentTestUtils.addEnviron
*/
public class SpringClientFactoryTests {
public static class ClientConfigInjectedByConstructor {
private IClientConfig clientConfig;
public ClientConfigInjectedByConstructor(IClientConfig clientConfig) {
this.clientConfig = clientConfig;
}
}
public static class ClientConfigInjectedByInitMethod implements IClientConfigAware {
private IClientConfig clientConfig;
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
this.clientConfig = clientConfig;
}
}
public static class NoClientConfigAware {
public NoClientConfigAware() {
// no client config
}
}
@Test
public void testConfigureRetry() {
......@@ -65,4 +94,25 @@ public class SpringClientFactoryTests {
.getHttpClient().getParams().getParameter(ClientPNames.COOKIE_POLICY));
factory.destroy();
}
@Test
public void testInstantiateWithConfigInjectByConstructor() {
IClientConfig clientConfig = new DefaultClientConfigImpl();
ClientConfigInjectedByConstructor instance = SpringClientFactory.instantiateWithConfig(ClientConfigInjectedByConstructor.class, clientConfig);
assertThat(instance.clientConfig).isSameAs(clientConfig);
}
@Test
public void testInstantiateWithConfigInjectedByInitMethod() {
IClientConfig clientConfig = new DefaultClientConfigImpl();
ClientConfigInjectedByInitMethod instance = SpringClientFactory.instantiateWithConfig(ClientConfigInjectedByInitMethod.class, clientConfig);
assertThat(instance.clientConfig).isSameAs(clientConfig);
}
@Test
public void testInstantiateWithoutConfig() {
IClientConfig clientConfig = new DefaultClientConfigImpl();
NoClientConfigAware instance = SpringClientFactory.instantiateWithConfig(NoClientConfigAware.class, clientConfig);
assertThat(instance).isNotNull();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment