BeanFactoryUtils returns all beans including beans defined in ancestor bean factories (#515)

pull/518/head
DerekYRC 2 years ago committed by GitHub
parent e7d5e2a67d
commit 4f3ed9321c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,3 +10,4 @@
- [Feature: zuul supports polaris router](https://github.com/Tencent/spring-cloud-tencent/pull/502) - [Feature: zuul supports polaris router](https://github.com/Tencent/spring-cloud-tencent/pull/502)
- [Refactor : optimize project and code](https://github.com/Tencent/spring-cloud-tencent/pull/506) - [Refactor : optimize project and code](https://github.com/Tencent/spring-cloud-tencent/pull/506)
- [Fix typo & Code optimization](https://github.com/Tencent/spring-cloud-tencent/pull/507) - [Fix typo & Code optimization](https://github.com/Tencent/spring-cloud-tencent/pull/507)
- [BugfixBeanFactoryUtils returns all beans including beans defined in ancestor bean factories](https://github.com/Tencent/spring-cloud-tencent/pull/515)

@ -18,15 +18,21 @@
package com.tencent.cloud.polaris.router.beanprocessor; package com.tencent.cloud.polaris.router.beanprocessor;
import java.util.List;
import com.netflix.loadbalancer.AbstractLoadBalancerRule; import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BestAvailableRule; import com.netflix.loadbalancer.BestAvailableRule;
import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule; import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RoundRobinRule; import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.loadbalancer.ZoneAvoidanceRule; import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.tencent.cloud.common.util.ReflectionUtils;
import com.tencent.cloud.polaris.loadbalancer.config.PolarisLoadBalancerProperties; import com.tencent.cloud.polaris.loadbalancer.config.PolarisLoadBalancerProperties;
import com.tencent.cloud.polaris.router.PolarisLoadBalancerCompositeRule; import com.tencent.cloud.polaris.router.PolarisLoadBalancerCompositeRule;
import com.tencent.cloud.polaris.router.config.RibbonConfiguration; import com.tencent.cloud.polaris.router.config.RibbonConfiguration;
import com.tencent.cloud.polaris.router.config.properties.PolarisNearByRouterProperties;
import com.tencent.cloud.polaris.router.interceptor.NearbyRouterRequestInterceptor;
import com.tencent.cloud.polaris.router.spi.RouterRequestInterceptor;
import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.client.api.SDKContext;
import com.tencent.polaris.router.api.core.RouterAPI; import com.tencent.polaris.router.api.core.RouterAPI;
import com.tencent.polaris.router.client.api.DefaultRouterAPI; import com.tencent.polaris.router.client.api.DefaultRouterAPI;
@ -34,6 +40,7 @@ import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
@ -42,6 +49,7 @@ import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
/** /**
* Test for {@link PolarisLoadBalancerCompositeRuleBeanPostProcessor}. * Test for {@link PolarisLoadBalancerCompositeRuleBeanPostProcessor}.
@ -57,12 +65,18 @@ public class PolarisLoadBalancerCompositeRuleBeanPostProcessorTest {
@Test @Test
public void test1() { public void test1() {
ApplicationContextRunner contextRunner = new ApplicationContextRunner() ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(RibbonDefaultConfig.class, PolarisRibbonTest.class, RibbonAutoConfiguration.class)); .withConfiguration(AutoConfigurations.of(
RibbonDefaultConfig.class,
PolarisRibbonTest.class,
RibbonAutoConfiguration.class,
RouterConfiguration.class));
contextRunner.run(context -> { contextRunner.run(context -> {
SpringClientFactory springClientFactory = context.getBean(SpringClientFactory.class); SpringClientFactory springClientFactory = context.getBean(SpringClientFactory.class);
IRule rule = springClientFactory.getInstance(SERVICE_1, IRule.class); IRule rule = springClientFactory.getInstance(SERVICE_1, IRule.class);
Assert.assertTrue(rule instanceof PolarisLoadBalancerCompositeRule); Assert.assertTrue(rule instanceof PolarisLoadBalancerCompositeRule);
List<RouterRequestInterceptor> requestInterceptors = (List<RouterRequestInterceptor>) ReflectionUtils.getFieldValue(rule, "requestInterceptors");
Assert.assertFalse(CollectionUtils.isEmpty(requestInterceptors));
AbstractLoadBalancerRule delegateRule = ((PolarisLoadBalancerCompositeRule) rule).getDelegateRule(); AbstractLoadBalancerRule delegateRule = ((PolarisLoadBalancerCompositeRule) rule).getDelegateRule();
//ZoneAvoidanceRule default //ZoneAvoidanceRule default
Assert.assertTrue(delegateRule instanceof ZoneAvoidanceRule); Assert.assertTrue(delegateRule instanceof ZoneAvoidanceRule);
@ -162,4 +176,14 @@ public class PolarisLoadBalancerCompositeRuleBeanPostProcessorTest {
return new DefaultRouterAPI(sdkContext); return new DefaultRouterAPI(sdkContext);
} }
} }
@Configuration
@EnableConfigurationProperties(PolarisNearByRouterProperties.class)
static class RouterConfiguration {
@Bean
@ConditionalOnProperty(value = "spring.cloud.polaris.router.nearby-router.enabled", matchIfMissing = true)
public NearbyRouterRequestInterceptor nearbyRouterRequestInterceptor(PolarisNearByRouterProperties polarisNearByRouterProperties) {
return new NearbyRouterRequestInterceptor(polarisNearByRouterProperties);
}
}
} }

@ -18,13 +18,14 @@
package com.tencent.cloud.common.util; package com.tencent.cloud.common.util;
import java.util.Arrays; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.Map;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.ListableBeanFactory;
import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors;
/** /**
* the utils for bean factory. * the utils for bean factory.
@ -36,19 +37,12 @@ public final class BeanFactoryUtils {
} }
public static <T> List<T> getBeans(BeanFactory beanFactory, Class<T> requiredType) { public static <T> List<T> getBeans(BeanFactory beanFactory, Class<T> requiredType) {
if (!(beanFactory instanceof DefaultListableBeanFactory)) { if (!(beanFactory instanceof ListableBeanFactory)) {
throw new RuntimeException("bean factory not support get list bean. factory type = " + beanFactory.getClass() throw new RuntimeException("bean factory not support get list bean. factory type = " + beanFactory.getClass()
.getName()); .getName());
} }
String[] beanNames = ((DefaultListableBeanFactory) beanFactory).getBeanNamesForType(requiredType); Map<String, T> beanMap = beansOfTypeIncludingAncestors((ListableBeanFactory) beanFactory, requiredType);
return new ArrayList<>(beanMap.values());
if (beanNames.length == 0) {
return Collections.emptyList();
}
return Arrays.stream(beanNames).map(
beanName -> beanFactory.getBean(beanName, requiredType)
).collect(Collectors.toList());
} }
} }

@ -0,0 +1,36 @@
package com.tencent.cloud.common.util;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
/**
* Test for {@link BeanFactoryUtils}.
*
* @author Derek Yi 2022-08-18
*/
public class BeanFactoryUtilsTest {
@Test
public void testGetBeansIncludingAncestors() {
DefaultListableBeanFactory parentBeanFactory = new DefaultListableBeanFactory();
parentBeanFactory.registerBeanDefinition("foo", new RootBeanDefinition(Foo.class));
DefaultListableBeanFactory childBeanFactory = new DefaultListableBeanFactory(parentBeanFactory);
Assert.assertTrue(childBeanFactory.getBeansOfType(Foo.class).isEmpty());
Assert.assertTrue(BeanFactoryUtils.getBeans(childBeanFactory, Foo.class).size() == 1);
Assert.assertTrue(BeanFactoryUtils.getBeans(childBeanFactory, Bar.class).isEmpty());
}
static class Foo {
}
static class Bar {
}
}
Loading…
Cancel
Save