You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by zh...@apache.org on 2022/06/11 10:27:17 UTC
[incubator-shenyu] branch master updated: [ISSUE #3484] fix springcloud client lossless registration (#3529)
This is an automated email from the ASF dual-hosted git repository.
zhangzicheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 75c4b5b4b [ISSUE #3484] fix springcloud client lossless registration (#3529)
75c4b5b4b is described below
commit 75c4b5b4b42eb2bb2a9f8f9fc0afdb99d3505dbf
Author: renzhuyan <40...@qq.com>
AuthorDate: Sat Jun 11 05:27:12 2022 -0500
[ISSUE #3484] fix springcloud client lossless registration (#3529)
* fix springcloud client lossless registration
---
...or.java => SpringCloudClientEventListener.java} | 37 +++++++++++--------
...ava => SpringCloudClientEventListenerTest.java} | 42 ++++++++++++++--------
.../ShenyuSpringCloudClientConfiguration.java | 10 +++---
.../ShenyuSpringCloudClientConfigurationTest.java | 4 +--
4 files changed, 57 insertions(+), 36 deletions(-)
diff --git a/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientBeanPostProcessor.java b/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientEventListener.java
similarity index 90%
rename from shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientBeanPostProcessor.java
rename to shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientEventListener.java
index 80479b35d..db85bb5ea 100644
--- a/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientBeanPostProcessor.java
+++ b/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/main/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientEventListener.java
@@ -31,8 +31,8 @@ import org.apache.shenyu.register.common.dto.MetaDataRegisterDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.support.AopUtils;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.Environment;
@@ -46,21 +46,22 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
/**
- * The type Shenyu client bean post processor.
+ * The type Spring cloud client event listener.
*/
-public class SpringCloudClientBeanPostProcessor implements BeanPostProcessor {
+public class SpringCloudClientEventListener implements ApplicationListener<ContextRefreshedEvent> {
/**
* api path separator.
*/
private static final String PATH_SEPARATOR = "/";
- private static final Logger LOG = LoggerFactory.getLogger(SpringCloudClientBeanPostProcessor.class);
+ private static final Logger LOG = LoggerFactory.getLogger(SpringCloudClientEventListener.class);
private final ShenyuClientRegisterEventPublisher publisher = ShenyuClientRegisterEventPublisher.getInstance();
@@ -83,9 +84,9 @@ public class SpringCloudClientBeanPostProcessor implements BeanPostProcessor {
* @param shenyuClientRegisterRepository the shenyu client register repository
* @param env the env
*/
- public SpringCloudClientBeanPostProcessor(final PropertiesConfig clientConfig,
- final ShenyuClientRegisterRepository shenyuClientRegisterRepository,
- final Environment env) {
+ public SpringCloudClientEventListener(final PropertiesConfig clientConfig,
+ final ShenyuClientRegisterRepository shenyuClientRegisterRepository,
+ final Environment env) {
String appName = env.getProperty("spring.application.name");
Properties props = clientConfig.getProps();
this.contextPath = Optional.ofNullable(props.getProperty(ShenyuClientConstants.CONTEXT_PATH)).map(UriUtils::repairData).orElse(null);
@@ -101,24 +102,31 @@ public class SpringCloudClientBeanPostProcessor implements BeanPostProcessor {
mappingAnnotation.add(RequestMapping.class);
publisher.start(shenyuClientRegisterRepository);
}
-
+
@Override
- public Object postProcessAfterInitialization(@NonNull final Object bean, @NonNull final String beanName) throws BeansException {
+ public void onApplicationEvent(final ContextRefreshedEvent contextRefreshedEvent) {
+ Map<String, Object> beans = contextRefreshedEvent.getApplicationContext().getBeansWithAnnotation(Controller.class);
+ for (Map.Entry<String, Object> entry : beans.entrySet()) {
+ handler(entry.getValue());
+ }
+ }
+
+ private void handler(final Object bean) {
Class<?> clazz = bean.getClass();
if (AopUtils.isAopProxy(bean)) {
clazz = AopUtils.getTargetClass(bean);
}
// Filter out is not controller out
- if (Boolean.TRUE.equals(isFull) || !hasAnnotation(clazz, Controller.class)) {
- return bean;
+ if (Boolean.TRUE.equals(isFull)) {
+ return;
}
-
+
final ShenyuSpringCloudClient beanShenyuClient = AnnotatedElementUtils.findMergedAnnotation(clazz, ShenyuSpringCloudClient.class);
final String superPath = buildApiSuperPath(clazz, beanShenyuClient);
// Compatible with previous versions
if (Objects.nonNull(beanShenyuClient) && superPath.contains("*")) {
publisher.publishEvent(buildMetaDataDTO(beanShenyuClient, pathJoin(contextPath, superPath)));
- return bean;
+ return;
}
final Method[] methods = ReflectionUtils.getUniqueDeclaredMethods(clazz);
for (Method method : methods) {
@@ -131,7 +139,6 @@ public class SpringCloudClientBeanPostProcessor implements BeanPostProcessor {
publisher.publishEvent(buildMetaDataDTO(methodShenyuClient, buildApiPath(method, superPath, methodShenyuClient)));
}
}
- return bean;
}
private <A extends Annotation> boolean hasAnnotation(final @NonNull Class<?> clazz, final @NonNull Class<A> annotationType) {
diff --git a/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/test/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientBeanPostProcessorTest.java b/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/test/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientEventListenerTest.java
similarity index 70%
rename from shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/test/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientBeanPostProcessorTest.java
rename to shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/test/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientEventListenerTest.java
index 7d352fb4a..921c40b72 100644
--- a/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/test/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientBeanPostProcessorTest.java
+++ b/shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/test/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientEventListenerTest.java
@@ -31,27 +31,31 @@ import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.stubbing.Answer;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Optional;
import java.util.Properties;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
- * Test for {@link SpringCloudClientBeanPostProcessor}.
+ * Test for {@link SpringCloudClientEventListener}.
*/
@ExtendWith(MockitoExtension.class)
@TestMethodOrder(MethodOrderer.Alphanumeric.class)
-public final class SpringCloudClientBeanPostProcessorTest {
+public final class SpringCloudClientEventListenerTest {
@Mock
private static Environment env;
@@ -60,27 +64,36 @@ public final class SpringCloudClientBeanPostProcessorTest {
private final SpringCloudClientTestBean springCloudClientTestBean = new SpringCloudClientTestBean();
+ @Mock
+ private ApplicationContext applicationContext;
+
+ private ContextRefreshedEvent contextRefreshedEvent;
+
@BeforeEach
public void init() {
when(env.getProperty("spring.application.name")).thenReturn("spring-cloud-test");
+ Map<String, Object> results = new LinkedHashMap();
+ results.put("springCloudClientTestBean", springCloudClientTestBean);
+ when(applicationContext.getBeansWithAnnotation(any())).thenReturn(results);
+ contextRefreshedEvent = new ContextRefreshedEvent(applicationContext);
}
@Test
public void testShenyuBeanProcess() {
registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.of("token"));
// config with full
- SpringCloudClientBeanPostProcessor springCloudClientBeanPostProcessor = buildSpringCloudClientBeanPostProcessor(true);
- assertThat(springCloudClientTestBean, equalTo(springCloudClientBeanPostProcessor.postProcessAfterInitialization(springCloudClientTestBean, "springCloudClientTestBean")));
+ SpringCloudClientEventListener springCloudClientEventListener = buildSpringCloudClienttEventListener(true);
+ springCloudClientEventListener.onApplicationEvent(contextRefreshedEvent);
+ verify(applicationContext, times(1)).getBeansWithAnnotation(any());
registerUtilsMockedStatic.close();
}
@Test
public void testNormalBeanProcess() {
registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.of("token"));
- SpringCloudClientBeanPostProcessor springCloudClientBeanPostProcessor = buildSpringCloudClientBeanPostProcessor(false);
- Object normalBean = new Object();
-
- assertThat(normalBean, equalTo(springCloudClientBeanPostProcessor.postProcessAfterInitialization(normalBean, "normalBean")));
+ SpringCloudClientEventListener springCloudClientEventListener = buildSpringCloudClienttEventListener(false);
+ springCloudClientEventListener.onApplicationEvent(contextRefreshedEvent);
+ verify(applicationContext, times(1)).getBeansWithAnnotation(any());
registerUtilsMockedStatic.close();
}
@@ -89,12 +102,13 @@ public final class SpringCloudClientBeanPostProcessorTest {
registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.of("token"));
registerUtilsMockedStatic.when(() -> RegisterUtils.doRegister(any(), any(), any()))
.thenAnswer((Answer<Void>) invocation -> null);
- SpringCloudClientBeanPostProcessor springCloudClientBeanPostProcessor = buildSpringCloudClientBeanPostProcessor(false);
- assertThat(springCloudClientTestBean, equalTo(springCloudClientBeanPostProcessor.postProcessAfterInitialization(springCloudClientTestBean, "normalBean")));
+ SpringCloudClientEventListener springCloudClientEventListener = buildSpringCloudClienttEventListener(false);
+ springCloudClientEventListener.onApplicationEvent(contextRefreshedEvent);
+ verify(applicationContext, times(1)).getBeansWithAnnotation(any());
registerUtilsMockedStatic.close();
}
- private SpringCloudClientBeanPostProcessor buildSpringCloudClientBeanPostProcessor(final boolean full) {
+ private SpringCloudClientEventListener buildSpringCloudClienttEventListener(final boolean full) {
Properties properties = new Properties();
properties.setProperty("contextPath", "/test");
properties.setProperty("isFull", full + "");
@@ -108,7 +122,7 @@ public final class SpringCloudClientBeanPostProcessorTest {
mockRegisterCenter.setServerLists("http://127.0.0.1:8080");
mockRegisterCenter.setRegisterType("http");
mockRegisterCenter.setProps(properties);
- return new SpringCloudClientBeanPostProcessor(config, ShenyuClientRegisterRepositoryFactory.newInstance(mockRegisterCenter), env);
+ return new SpringCloudClientEventListener(config, ShenyuClientRegisterRepositoryFactory.newInstance(mockRegisterCenter), env);
}
@RestController
diff --git a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springcloud/src/main/java/org/apache/shenyu/springboot/starter/client/springcloud/ShenyuSpringCloudClientConfiguration.java b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springcloud/src/main/java/org/apache/shenyu/springboot/starter/client/springcloud/ShenyuSpringCloudClientConfiguration.java
index e58fddc41..96d607cea 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springcloud/src/main/java/org/apache/shenyu/springboot/starter/client/springcloud/ShenyuSpringCloudClientConfiguration.java
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springcloud/src/main/java/org/apache/shenyu/springboot/starter/client/springcloud/ShenyuSpringCloudClientConfiguration.java
@@ -18,7 +18,7 @@
package org.apache.shenyu.springboot.starter.client.springcloud;
import org.apache.shenyu.client.springcloud.init.ContextRegisterListener;
-import org.apache.shenyu.client.springcloud.init.SpringCloudClientBeanPostProcessor;
+import org.apache.shenyu.client.springcloud.init.SpringCloudClientEventListener;
import org.apache.shenyu.common.enums.RpcTypeEnum;
import org.apache.shenyu.register.client.api.ShenyuClientRegisterRepository;
import org.apache.shenyu.register.common.config.ShenyuClientConfig;
@@ -44,10 +44,10 @@ public class ShenyuSpringCloudClientConfiguration {
* @return the spring cloud client bean post processor
*/
@Bean
- public SpringCloudClientBeanPostProcessor springCloudClientBeanPostProcessor(final ShenyuClientConfig clientConfig,
- final ShenyuClientRegisterRepository shenyuClientRegisterRepository,
- final Environment env) {
- return new SpringCloudClientBeanPostProcessor(clientConfig.getClient().get(RpcTypeEnum.SPRING_CLOUD.getName()), shenyuClientRegisterRepository, env);
+ public SpringCloudClientEventListener springCloudClientEventListener(final ShenyuClientConfig clientConfig,
+ final ShenyuClientRegisterRepository shenyuClientRegisterRepository,
+ final Environment env) {
+ return new SpringCloudClientEventListener(clientConfig.getClient().get(RpcTypeEnum.SPRING_CLOUD.getName()), shenyuClientRegisterRepository, env);
}
/**
diff --git a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springcloud/src/test/java/org/apache/shenyu/springboot/starter/client/springcloud/ShenyuSpringCloudClientConfigurationTest.java b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springcloud/src/test/java/org/apache/shenyu/springboot/starter/client/springcloud/ShenyuSpringCloudClientConfigurationTest.java
index 3520d5ab3..4dbe1cdf1 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springcloud/src/test/java/org/apache/shenyu/springboot/starter/client/springcloud/ShenyuSpringCloudClientConfigurationTest.java
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springcloud/src/test/java/org/apache/shenyu/springboot/starter/client/springcloud/ShenyuSpringCloudClientConfigurationTest.java
@@ -18,7 +18,7 @@
package org.apache.shenyu.springboot.starter.client.springcloud;
import org.apache.shenyu.client.springcloud.init.ContextRegisterListener;
-import org.apache.shenyu.client.springcloud.init.SpringCloudClientBeanPostProcessor;
+import org.apache.shenyu.client.springcloud.init.SpringCloudClientEventListener;
import org.apache.shenyu.register.client.http.utils.RegisterUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -65,7 +65,7 @@ public class ShenyuSpringCloudClientConfigurationTest {
MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
applicationContextRunner.run(context -> {
- SpringCloudClientBeanPostProcessor repository = context.getBean("springCloudClientBeanPostProcessor", SpringCloudClientBeanPostProcessor.class);
+ SpringCloudClientEventListener repository = context.getBean("springCloudClientEventListener", SpringCloudClientEventListener.class);
assertNotNull(repository);
});
registerUtilsMockedStatic.close();