This is an automated email from the ASF dual-hosted git repository.
crazyhzm pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.3 by this push:
new 4604b8074a Support for automatic identification of serialization
classes and generation of native image configuration (#12433)
4604b8074a is described below
commit 4604b8074ab8bc60ce3eac2a54ed0e54457fea58
Author: huazhongming <[email protected]>
AuthorDate: Wed May 31 16:05:54 2023 +0800
Support for automatic identification of serialization classes and
generation of native image configuration (#12433)
Signed-off-by: crazyhzm <[email protected]>
---
...eferenceAnnotationWithAotBeanPostProcessor.java | 76 +++++++++++-----------
.../ServiceAnnotationWithAotPostProcessor.java | 4 +-
.../dubbo/config/spring6/utils/AotUtils.java | 41 ++++++++++++
3 files changed, 83 insertions(+), 38 deletions(-)
diff --git
a/dubbo-config/dubbo-config-spring6/src/main/java/org/apache/dubbo/config/spring6/beans/factory/annotation/ReferenceAnnotationWithAotBeanPostProcessor.java
b/dubbo-config/dubbo-config-spring6/src/main/java/org/apache/dubbo/config/spring6/beans/factory/annotation/ReferenceAnnotationWithAotBeanPostProcessor.java
index bcb2917b88..54d660b14c 100644
---
a/dubbo-config/dubbo-config-spring6/src/main/java/org/apache/dubbo/config/spring6/beans/factory/annotation/ReferenceAnnotationWithAotBeanPostProcessor.java
+++
b/dubbo-config/dubbo-config-spring6/src/main/java/org/apache/dubbo/config/spring6/beans/factory/annotation/ReferenceAnnotationWithAotBeanPostProcessor.java
@@ -35,6 +35,7 @@ import
org.apache.dubbo.config.spring.reference.ReferenceBeanSupport;
import org.apache.dubbo.config.spring.util.SpringCompatUtils;
import
org.apache.dubbo.config.spring6.beans.factory.aot.ReferencedFieldValueResolver;
import
org.apache.dubbo.config.spring6.beans.factory.aot.ReferencedMethodArgumentsResolver;
+import org.apache.dubbo.config.spring6.utils.AotUtils;
import org.apache.dubbo.rpc.service.Destroyable;
import org.apache.dubbo.rpc.service.EchoService;
import org.apache.dubbo.rpc.service.GenericService;
@@ -120,7 +121,7 @@ import static org.springframework.util.StringUtils.hasText;
* @since 2.5.7
*/
public class ReferenceAnnotationWithAotBeanPostProcessor extends
AbstractAnnotationBeanPostProcessor
- implements ApplicationContextAware, BeanRegistrationAotProcessor,
BeanFactoryPostProcessor {
+ implements ApplicationContextAware, BeanRegistrationAotProcessor,
BeanFactoryPostProcessor {
/**
* The bean name of {@link ReferenceAnnotationWithAotBeanPostProcessor}
@@ -135,10 +136,10 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
private final ErrorTypeAwareLogger logger =
LoggerFactory.getErrorTypeAwareLogger(getClass());
private final ConcurrentMap<InjectionMetadata.InjectedElement, String>
injectedFieldReferenceBeanCache =
- new ConcurrentHashMap<>(CACHE_SIZE);
+ new ConcurrentHashMap<>(CACHE_SIZE);
private final ConcurrentMap<InjectionMetadata.InjectedElement, String>
injectedMethodReferenceBeanCache =
- new ConcurrentHashMap<>(CACHE_SIZE);
+ new ConcurrentHashMap<>(CACHE_SIZE);
private ApplicationContext applicationContext;
@@ -262,8 +263,8 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
if (beanClass == null) {
String beanMethodSignature =
factoryMethodMetadata.getDeclaringClassName() + "#" +
factoryMethodMetadata.getMethodName() + "()";
throw new BeanCreationException("The ReferenceBean is missing
necessary generic type, which returned by the @Bean method of Java-config
class. " +
- "The generic type of the returned ReferenceBean must be
specified as the referenced interface type, " +
- "such as ReferenceBean<DemoService>. Please check bean method:
" + beanMethodSignature);
+ "The generic type of the returned ReferenceBean must be
specified as the referenced interface type, " +
+ "such as ReferenceBean<DemoService>. Please check bean
method: " + beanMethodSignature);
}
// get dubbo reference annotation attributes
@@ -295,10 +296,10 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
if (!StringUtils.isEquals(interfaceName, beanClass.getName()) &&
beanClass != GenericService.class) {
String beanMethodSignature =
factoryMethodMetadata.getDeclaringClassName() + "#" +
factoryMethodMetadata.getMethodName() + "()";
throw new BeanCreationException("The 'interfaceClass' or
'interfaceName' attribute value of @DubboReference annotation " +
- "is inconsistent with the generic type of the
ReferenceBean returned by the bean method. " +
- "The interface class of @DubboReference is: " +
interfaceName + ", but return ReferenceBean<" + beanClass.getName() + ">. " +
- "Please remove the 'interfaceClass' and 'interfaceName'
attributes from @DubboReference annotation. " +
- "Please check bean method: " + beanMethodSignature);
+ "is inconsistent with the generic type of the
ReferenceBean returned by the bean method. " +
+ "The interface class of @DubboReference is: " +
interfaceName + ", but return ReferenceBean<" + beanClass.getName() + ">. " +
+ "Please remove the 'interfaceClass' and
'interfaceName' attributes from @DubboReference annotation. " +
+ "Please check bean method: " + beanMethodSignature);
}
Class interfaceClass = beanClass;
@@ -352,7 +353,7 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
* @see #postProcessProperties
*/
public PropertyValues postProcessPropertyValues(
- PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String
beanName) throws BeansException {
+ PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String
beanName) throws BeansException {
return postProcessProperties(pvs, bean, beanName);
}
@@ -363,7 +364,7 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
*/
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object
bean, String beanName)
- throws BeansException {
+ throws BeansException {
try {
AnnotatedInjectionMetadata metadata =
findInjectionMetadata(beanName, bean.getClass(), pvs);
prepareInjection(metadata);
@@ -372,7 +373,7 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of @" +
getAnnotationType().getSimpleName()
- + " dependencies is failed", ex);
+ + " dependencies is failed", ex);
}
return pvs;
}
@@ -504,16 +505,16 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
// bean name from attribute 'id' or java-config bean, cannot be
renamed
if (!renameable) {
throw new BeanCreationException("Already exists another bean
definition with the same bean name [" + referenceBeanName + "], " +
- "but cannot rename the reference bean name (specify the id
attribute or java-config bean), " +
- "please modify the name of one of the beans: " +
- "prev: " + prevBeanDesc + ", new: " + newBeanDesc + ". " +
checkLocation);
+ "but cannot rename the reference bean name (specify
the id attribute or java-config bean), " +
+ "please modify the name of one of the beans: " +
+ "prev: " + prevBeanDesc + ", new: " + newBeanDesc + ".
" + checkLocation);
}
// the prev bean type is different, rename the new reference bean
int index = 2;
String newReferenceBeanName = null;
while (newReferenceBeanName == null ||
beanDefinitionRegistry.containsBeanDefinition(newReferenceBeanName)
- || beanDefinitionRegistry.isAlias(newReferenceBeanName)) {
+ || beanDefinitionRegistry.isAlias(newReferenceBeanName)) {
newReferenceBeanName = referenceBeanName + "#" + index;
index++;
// double check found same name and reference key
@@ -524,9 +525,9 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
newBeanDesc = newReferenceBeanName + "[" + referenceKey + "]";
logger.warn(CONFIG_DUBBO_BEAN_INITIALIZER, "", "", "Already exists
another bean definition with the same bean name [" + referenceBeanName + "], " +
- "rename dubbo reference bean to [" + newReferenceBeanName +
"]. " +
- "It is recommended to modify the name of one of the beans to
avoid injection problems. " +
- "prev: " + prevBeanDesc + ", new: " + newBeanDesc + ". " +
checkLocation);
+ "rename dubbo reference bean to [" + newReferenceBeanName
+ "]. " +
+ "It is recommended to modify the name of one of the beans
to avoid injection problems. " +
+ "prev: " + prevBeanDesc + ", new: " + newBeanDesc + ". " +
checkLocation);
referenceBeanName = newReferenceBeanName;
}
attributes.put(ReferenceAttributes.ID, referenceBeanName);
@@ -664,19 +665,19 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
@Override
public void applyTo(GenerationContext generationContext,
BeanRegistrationCode beanRegistrationCode) {
GeneratedClass generatedClass =
generationContext.getGeneratedClasses()
- .addForFeatureComponent("DubboReference", this.target, type ->
{
- type.addJavadoc("DubboReference for {@link $T}.",
this.target);
-
type.addModifiers(javax.lang.model.element.Modifier.PUBLIC);
- });
+ .addForFeatureComponent("DubboReference", this.target,
type -> {
+ type.addJavadoc("DubboReference for {@link $T}.",
this.target);
+
type.addModifiers(javax.lang.model.element.Modifier.PUBLIC);
+ });
GeneratedMethod generateMethod =
generatedClass.getMethods().add("apply", method -> {
method.addJavadoc("Apply the dubbo reference.");
method.addModifiers(javax.lang.model.element.Modifier.PUBLIC,
- javax.lang.model.element.Modifier.STATIC);
+ javax.lang.model.element.Modifier.STATIC);
method.addParameter(RegisteredBean.class,
REGISTERED_BEAN_PARAMETER);
method.addParameter(this.target, INSTANCE_PARAMETER);
method.returns(this.target);
method.addCode(generateMethodCode(generatedClass.getName(),
- generationContext.getRuntimeHints()));
+ generationContext.getRuntimeHints()));
});
beanRegistrationCode.addInstancePostProcessor(generateMethod.toMethodReference());
@@ -690,13 +691,13 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
if
(!CollectionUtils.isEmpty(this.annotatedInjectionMetadata.getFieldElements())) {
for (AnnotatedInjectElement referenceElement :
this.annotatedInjectionMetadata.getFieldElements()) {
code.addStatement(generateMethodStatementForElement(
- targetClassName, referenceElement, hints));
+ targetClassName, referenceElement, hints));
}
}
if
(!CollectionUtils.isEmpty(this.annotatedInjectionMetadata.getMethodElements()))
{
for (AnnotatedInjectElement referenceElement :
this.annotatedInjectionMetadata.getMethodElements()) {
code.addStatement(generateMethodStatementForElement(
- targetClassName, referenceElement, hints));
+ targetClassName, referenceElement, hints));
}
}
code.addStatement("return $L", INSTANCE_PARAMETER);
@@ -712,6 +713,7 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
try {
Class<?> c = referenceElement.getInjectedType();
+ AotUtils.registerSerializationHint(c, hints);
hints.reflection().registerType(TypeReference.of(c),
MemberCategory.INVOKE_PUBLIC_METHODS);
hints.proxies().registerJdkProxy(c, EchoService.class,
Destroyable.class);
hints.proxies().registerJdkProxy(c, EchoService.class,
Destroyable.class, SpringProxy.class, Advised.class, DecoratingProxy.class);
@@ -721,14 +723,14 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
if (member instanceof Field) {
return generateMethodStatementForField(
- targetClassName, (Field) member, attributes,
injectedObject, hints);
+ targetClassName, (Field) member, attributes,
injectedObject, hints);
}
if (member instanceof Method) {
return generateMethodStatementForMethod(
- targetClassName, (Method) member, attributes,
injectedObject, hints);
+ targetClassName, (Method) member, attributes,
injectedObject, hints);
}
throw new IllegalStateException(
- "Unsupported member type " + member.getClass().getName());
+ "Unsupported member type " + member.getClass().getName());
}
private CodeBlock generateMethodStatementForField(ClassName
targetClassName,
@@ -736,17 +738,17 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
hints.reflection().registerField(field);
CodeBlock resolver = CodeBlock.of("$T.$L($S)",
- ReferencedFieldValueResolver.class,
- "forRequiredField", field.getName());
+ ReferencedFieldValueResolver.class,
+ "forRequiredField", field.getName());
CodeBlock shortcutResolver = CodeBlock.of("$L.withShortcut($S)",
resolver, injectedObject);
AccessControl accessControl = AccessControl.forMember(field);
if (!accessControl.isAccessibleFrom(targetClassName)) {
return CodeBlock.of("$L.resolveAndSet($L, $L)",
shortcutResolver,
- REGISTERED_BEAN_PARAMETER, INSTANCE_PARAMETER);
+ REGISTERED_BEAN_PARAMETER, INSTANCE_PARAMETER);
}
return CodeBlock.of("$L.$L = $L.resolve($L)", INSTANCE_PARAMETER,
- field.getName(), shortcutResolver, REGISTERED_BEAN_PARAMETER);
+ field.getName(), shortcutResolver,
REGISTERED_BEAN_PARAMETER);
}
private CodeBlock generateMethodStatementForMethod(ClassName
targetClassName,
@@ -774,9 +776,9 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
} else {
hints.reflection().registerMethod(method,
ExecutableMode.INTROSPECT);
CodeBlock arguments = new
AutowiredArgumentsCodeGenerator(this.target,
- method).generateCode(method.getParameterTypes());
+ method).generateCode(method.getParameterTypes());
CodeBlock injectionCode = CodeBlock.of("args -> $L.$L($L)",
- INSTANCE_PARAMETER, method.getName(), arguments);
+ INSTANCE_PARAMETER, method.getName(), arguments);
code.add(".resolve($L, $L)", REGISTERED_BEAN_PARAMETER,
injectionCode);
}
return code.build();
@@ -830,7 +832,7 @@ public class ReferenceAnnotationWithAotBeanPostProcessor
extends AbstractAnnotat
private void registerProxyIfNecessary(RuntimeHints runtimeHints,
DependencyDescriptor dependencyDescriptor) {
if (this.candidateResolver != null) {
Class<?> proxyClass =
-
this.candidateResolver.getLazyResolutionProxyClass(dependencyDescriptor, null);
+
this.candidateResolver.getLazyResolutionProxyClass(dependencyDescriptor, null);
if (proxyClass != null) {
ClassHintUtils.registerProxyIfNecessary(proxyClass,
runtimeHints);
}
diff --git
a/dubbo-config/dubbo-config-spring6/src/main/java/org/apache/dubbo/config/spring6/beans/factory/annotation/ServiceAnnotationWithAotPostProcessor.java
b/dubbo-config/dubbo-config-spring6/src/main/java/org/apache/dubbo/config/spring6/beans/factory/annotation/ServiceAnnotationWithAotPostProcessor.java
index 384754803a..ee5b17d001 100644
---
a/dubbo-config/dubbo-config-spring6/src/main/java/org/apache/dubbo/config/spring6/beans/factory/annotation/ServiceAnnotationWithAotPostProcessor.java
+++
b/dubbo-config/dubbo-config-spring6/src/main/java/org/apache/dubbo/config/spring6/beans/factory/annotation/ServiceAnnotationWithAotPostProcessor.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.ServiceBean;
import
org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationPostProcessor;
import org.apache.dubbo.config.spring.schema.AnnotationBeanDefinitionParser;
+import org.apache.dubbo.config.spring6.utils.AotUtils;
import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.TypeReference;
@@ -86,7 +87,8 @@ public class ServiceAnnotationWithAotPostProcessor extends
ServiceAnnotationPost
@Override
public void applyTo(GenerationContext generationContext,
BeanRegistrationCode beanRegistrationCode) {
generationContext.getRuntimeHints().reflection().registerType(TypeReference.of(cl),
- MemberCategory.INVOKE_PUBLIC_METHODS);
+ MemberCategory.INVOKE_PUBLIC_METHODS);
+ AotUtils.registerSerializationHint(cl,
generationContext.getRuntimeHints());
}
}
diff --git
a/dubbo-config/dubbo-config-spring6/src/main/java/org/apache/dubbo/config/spring6/utils/AotUtils.java
b/dubbo-config/dubbo-config-spring6/src/main/java/org/apache/dubbo/config/spring6/utils/AotUtils.java
new file mode 100644
index 0000000000..b6b686aee8
--- /dev/null
+++
b/dubbo-config/dubbo-config-spring6/src/main/java/org/apache/dubbo/config/spring6/utils/AotUtils.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dubbo.config.spring6.utils;
+
+import org.springframework.aot.hint.RuntimeHints;
+import org.springframework.aot.hint.TypeReference;
+
+import java.util.Arrays;
+
+
+public class AotUtils {
+
+ private AotUtils(){
+
+ }
+
+ public static void registerSerializationHint(Class<?> injectType,
RuntimeHints hints) {
+ Arrays.stream(injectType.getMethods()).forEach((method) -> {
+ Arrays.stream(method.getParameterTypes()).forEach((cl) -> {
+ hints.serialization().registerType(TypeReference.of(cl));
+ });
+
+
hints.serialization().registerType(TypeReference.of(method.getReturnType()));
+ });
+ }
+}