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/12 08:59:10 UTC
[incubator-shenyu] branch master updated: [ISSUE #3484] springmvc client lossless registration (#3537)
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 7c1c7a5f7 [ISSUE #3484] springmvc client lossless registration (#3537)
7c1c7a5f7 is described below
commit 7c1c7a5f7ece4cb92bb3f1f18d7324ccfc054700
Author: chuang <49...@users.noreply.github.com>
AuthorDate: Sun Jun 12 16:59:05 2022 +0800
[ISSUE #3484] springmvc client lossless registration (#3537)
---
...ssor.java => SpringMvcClientEventListener.java} | 94 +++++++++++-----------
.../src/main/resources/context/shenyu.xml | 4 +-
.../src/main/resources/context/shenyu.xml | 4 +-
...enyuSpringWebSocketClientConfigurationTest.java | 2 +-
.../ShenyuSpringMvcClientConfiguration.java | 14 ++--
.../ShenyuSpringMvcClientConfigurationTest.java | 6 +-
6 files changed, 63 insertions(+), 61 deletions(-)
diff --git a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/init/SpringMvcClientBeanPostProcessor.java b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/init/SpringMvcClientEventListener.java
similarity index 84%
rename from shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/init/SpringMvcClientBeanPostProcessor.java
rename to shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/init/SpringMvcClientEventListener.java
index ebe51f231..360476384 100644
--- a/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/init/SpringMvcClientBeanPostProcessor.java
+++ b/shenyu-client/shenyu-client-http/shenyu-client-springmvc/src/main/java/org/apache/shenyu/client/springmvc/init/SpringMvcClientEventListener.java
@@ -32,7 +32,8 @@ 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.lang.NonNull;
@@ -48,43 +49,44 @@ import org.springframework.web.bind.annotation.RequestMapping;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Map;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
/**
- * The type Shenyu spring mvc client bean post processor.
+ * The type Shenyu spring mvc client event listener.
*/
-public class SpringMvcClientBeanPostProcessor implements BeanPostProcessor {
-
+public class SpringMvcClientEventListener implements ApplicationListener<ContextRefreshedEvent> {
+
/**
* api path separator.
*/
private static final String PATH_SEPARATOR = "/";
-
- private static final Logger LOG = LoggerFactory.getLogger(SpringMvcClientBeanPostProcessor.class);
-
+
+ private static final Logger LOG = LoggerFactory.getLogger(SpringMvcClientEventListener.class);
+
private final ShenyuClientRegisterEventPublisher publisher = ShenyuClientRegisterEventPublisher.getInstance();
-
+
private final String contextPath;
-
+
private final String appName;
-
+
private final Boolean isFull;
-
+
private final List<Class<? extends Annotation>> mappingAnnotation = new ArrayList<>(7);
-
+
private final String[] pathAttributeNames = new String[]{"path", "value"};
-
+
/**
- * Instantiates a new Spring mvc client bean post processor.
+ * Instantiates a new Spring mvc client event listener.
*
* @param clientConfig the client config
* @param shenyuClientRegisterRepository the shenyu client register repository
*/
- public SpringMvcClientBeanPostProcessor(final PropertiesConfig clientConfig,
- final ShenyuClientRegisterRepository shenyuClientRegisterRepository) {
+ public SpringMvcClientEventListener(final PropertiesConfig clientConfig,
+ final ShenyuClientRegisterRepository shenyuClientRegisterRepository) {
Properties props = clientConfig.getProps();
this.appName = props.getProperty(ShenyuClientConstants.APP_NAME);
this.contextPath = Optional.ofNullable(props.getProperty(ShenyuClientConstants.CONTEXT_PATH)).map(UriUtils::repairData).orElse("");
@@ -102,24 +104,30 @@ public class SpringMvcClientBeanPostProcessor 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 event) throws BeansException {
+ // Filter out
+ if (Boolean.TRUE.equals(isFull)) {
+ return;
+ }
+ Map<String, Object> controllerBeans = event.getApplicationContext().getBeansWithAnnotation(Controller.class);
+ for (Map.Entry<String, Object> entry : controllerBeans.entrySet()) {
+ handler(entry.getValue());
+ }
+ }
+
+ private void handler(@NonNull 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(bean.getClass(), Controller.class)) {
- return bean;
- }
-
final ShenyuSpringMvcClient beanShenyuClient = AnnotatedElementUtils.findMergedAnnotation(clazz, ShenyuSpringMvcClient.class);
final String superPath = buildApiSuperPath(clazz);
// 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) {
@@ -132,14 +140,8 @@ public class SpringMvcClientBeanPostProcessor implements BeanPostProcessor {
publisher.publishEvent(buildMetaDataDTO(methodShenyuClient, buildApiPath(method, superPath)));
}
}
-
- return bean;
}
-
- private <A extends Annotation> boolean hasAnnotation(final @NonNull Class<?> clazz, final @NonNull Class<A> annotationType) {
- return Objects.nonNull(AnnotationUtils.findAnnotation(clazz, annotationType));
- }
-
+
private String buildApiPath(@NonNull final Method method, @NonNull final String superPath) {
ShenyuSpringMvcClient shenyuSpringMvcClient = AnnotatedElementUtils.findMergedAnnotation(method, ShenyuSpringMvcClient.class);
if (Objects.nonNull(shenyuSpringMvcClient) && StringUtils.isNotBlank(shenyuSpringMvcClient.path())) {
@@ -151,7 +153,7 @@ public class SpringMvcClientBeanPostProcessor implements BeanPostProcessor {
}
return pathJoin(contextPath, superPath);
}
-
+
private String getPathByMethod(@NonNull final Method method) {
for (Class<? extends Annotation> mapping : mappingAnnotation) {
final String pathByAnnotation = getPathByAnnotation(AnnotationUtils.findAnnotation(method, mapping), pathAttributeNames);
@@ -161,7 +163,7 @@ public class SpringMvcClientBeanPostProcessor implements BeanPostProcessor {
}
return null;
}
-
+
private String getPathByAnnotation(@Nullable final Annotation annotation, @NonNull final String... pathAttributeName) {
if (Objects.isNull(annotation)) {
return null;
@@ -178,7 +180,7 @@ public class SpringMvcClientBeanPostProcessor implements BeanPostProcessor {
}
return null;
}
-
+
private String buildApiSuperPath(@NonNull final Class<?> method) {
ShenyuSpringMvcClient shenyuSpringMvcClient = AnnotatedElementUtils.findMergedAnnotation(method, ShenyuSpringMvcClient.class);
if (Objects.nonNull(shenyuSpringMvcClient) && StringUtils.isNotBlank(shenyuSpringMvcClient.path())) {
@@ -191,7 +193,7 @@ public class SpringMvcClientBeanPostProcessor implements BeanPostProcessor {
}
return "";
}
-
+
private String pathJoin(@NonNull final String... path) {
StringBuilder result = new StringBuilder(PATH_SEPARATOR);
for (String p : path) {
@@ -202,18 +204,18 @@ public class SpringMvcClientBeanPostProcessor implements BeanPostProcessor {
}
return result.toString();
}
-
+
private MetaDataRegisterDTO buildMetaDataDTO(@NonNull final ShenyuSpringMvcClient shenyuSpringMvcClient, final String path) {
return MetaDataRegisterDTO.builder()
- .contextPath(contextPath)
- .appName(appName)
- .path(path)
- .pathDesc(shenyuSpringMvcClient.desc())
- .rpcType(RpcTypeEnum.HTTP.getName())
- .enabled(shenyuSpringMvcClient.enabled())
- .ruleName(StringUtils.defaultIfBlank(shenyuSpringMvcClient.ruleName(), path))
- .registerMetaData(shenyuSpringMvcClient.registerMetaData())
- .build();
+ .contextPath(contextPath)
+ .appName(appName)
+ .path(path)
+ .pathDesc(shenyuSpringMvcClient.desc())
+ .rpcType(RpcTypeEnum.HTTP.getName())
+ .enabled(shenyuSpringMvcClient.enabled())
+ .ruleName(StringUtils.defaultIfBlank(shenyuSpringMvcClient.ruleName(), path))
+ .registerMetaData(shenyuSpringMvcClient.registerMetaData())
+ .build();
}
-
+
}
diff --git a/shenyu-examples/shenyu-examples-springmvc-tomcat/src/main/resources/context/shenyu.xml b/shenyu-examples/shenyu-examples-springmvc-tomcat/src/main/resources/context/shenyu.xml
index a073563c4..6b31081f8 100644
--- a/shenyu-examples/shenyu-examples-springmvc-tomcat/src/main/resources/context/shenyu.xml
+++ b/shenyu-examples/shenyu-examples-springmvc-tomcat/src/main/resources/context/shenyu.xml
@@ -47,8 +47,8 @@
<constructor-arg ref="shenyuRegisterCenterConfig"/>
</bean>
- <bean id="springMvcClientBeanPostProcessor"
- class="org.apache.shenyu.client.springmvc.init.SpringMvcClientBeanPostProcessor">
+ <bean id="SpringMvcClientEventListener"
+ class="org.apache.shenyu.client.springmvc.init.SpringMvcClientEventListener">
<constructor-arg ref="clientPropertiesConfig"/>
<constructor-arg ref="clientRegisterRepository"/>
</bean>
diff --git a/shenyu-examples/shenyu-examples-springmvc/src/main/resources/context/shenyu.xml b/shenyu-examples/shenyu-examples-springmvc/src/main/resources/context/shenyu.xml
index 161879207..7583970fa 100644
--- a/shenyu-examples/shenyu-examples-springmvc/src/main/resources/context/shenyu.xml
+++ b/shenyu-examples/shenyu-examples-springmvc/src/main/resources/context/shenyu.xml
@@ -19,8 +19,8 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
- <bean id="springMvcClientBeanPostProcessor"
- class="org.apache.shenyu.client.springmvc.init.SpringMvcClientBeanPostProcessor">
+ <bean id="SpringMvcClientEventListener"
+ class="org.apache.shenyu.client.springmvc.init.SpringMvcClientEventListener">
<constructor-arg ref="clientPropertiesConfig"/>
<constructor-arg ref="clientRegisterRepository"/>
</bean>
diff --git a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-spring-websocket/src/test/java/org/apache/shenyu/springboot/starter/client/spring/websocket/ShenyuSpringWebSocketClientConfigurationTest.java b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-spring-websocket/src/test/java/org/apache/shenyu/springboot/starter/client/spring/websocket/ShenyuSpringWebSocketClientConfigurationTest.java
index a34048e25..8efb3f426 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-spring-websocket/src/test/java/org/apache/shenyu/springboot/starter/client/spring/websocket/ShenyuSpringWebSocketClientConfigurationTest.java
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-spring-websocket/src/test/java/org/apache/shenyu/springboot/starter/client/spring/websocket/ShenyuSpringWebSocketClientConfigurationTest.java
@@ -60,7 +60,7 @@ public class ShenyuSpringWebSocketClientConfigurationTest {
}
@Test
- public void testSpringMvcClientBeanPostProcessor() {
+ public void testSpringWebSocketClientBeanPostProcessor() {
MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
applicationContextRunner.run(context -> {
diff --git a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/main/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientConfiguration.java b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/main/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientConfiguration.java
index b7d368bda..4f93b63fc 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/main/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientConfiguration.java
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/main/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientConfiguration.java
@@ -18,7 +18,7 @@
package org.apache.shenyu.springboot.starter.client.springmvc;
import org.apache.shenyu.client.springmvc.init.ContextRegisterListener;
-import org.apache.shenyu.client.springmvc.init.SpringMvcClientBeanPostProcessor;
+import org.apache.shenyu.client.springmvc.init.SpringMvcClientEventListener;
import org.apache.shenyu.common.enums.RpcTypeEnum;
import org.apache.shenyu.register.client.api.ShenyuClientRegisterRepository;
import org.apache.shenyu.register.common.config.ShenyuClientConfig;
@@ -33,20 +33,20 @@ import org.springframework.context.annotation.Configuration;
@Configuration
@ImportAutoConfiguration(ShenyuClientCommonBeanConfiguration.class)
public class ShenyuSpringMvcClientConfiguration {
-
+
/**
* Spring mvc client bean post processor.
*
- * @param clientConfig the client config
+ * @param clientConfig the client config
* @param shenyuClientRegisterRepository the shenyu client register repository
* @return the spring mvc client bean post processor
*/
@Bean
- public SpringMvcClientBeanPostProcessor springHttpClientBeanPostProcessor(final ShenyuClientConfig clientConfig,
- final ShenyuClientRegisterRepository shenyuClientRegisterRepository) {
- return new SpringMvcClientBeanPostProcessor(clientConfig.getClient().get(RpcTypeEnum.HTTP.getName()), shenyuClientRegisterRepository);
+ public SpringMvcClientEventListener springHttpClientEventListener(final ShenyuClientConfig clientConfig,
+ final ShenyuClientRegisterRepository shenyuClientRegisterRepository) {
+ return new SpringMvcClientEventListener(clientConfig.getClient().get(RpcTypeEnum.HTTP.getName()), shenyuClientRegisterRepository);
}
-
+
/**
* Context register listener.
*
diff --git a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/test/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientConfigurationTest.java b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/test/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientConfigurationTest.java
index 6f5c4ecef..d2a517f10 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/test/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientConfigurationTest.java
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/test/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientConfigurationTest.java
@@ -18,7 +18,7 @@
package org.apache.shenyu.springboot.starter.client.springmvc;
import org.apache.shenyu.client.springmvc.init.ContextRegisterListener;
-import org.apache.shenyu.client.springmvc.init.SpringMvcClientBeanPostProcessor;
+import org.apache.shenyu.client.springmvc.init.SpringMvcClientEventListener;
import org.apache.shenyu.register.client.http.utils.RegisterUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -61,11 +61,11 @@ public class ShenyuSpringMvcClientConfigurationTest {
}
@Test
- public void testSpringMvcClientBeanPostProcessor() {
+ public void testSpringMvcClientEventListener() {
MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
applicationContextRunner.run(context -> {
- SpringMvcClientBeanPostProcessor processor = context.getBean("springHttpClientBeanPostProcessor", SpringMvcClientBeanPostProcessor.class);
+ SpringMvcClientEventListener processor = context.getBean("springHttpClientEventListener", SpringMvcClientEventListener.class);
assertNotNull(processor);
});
registerUtilsMockedStatic.close();