
io.github.linyimin0812.async.bean.AsyncInitBeanFinder Maven / Gradle / Ivy
package io.github.linyimin0812.async.bean;
import io.github.linyimin0812.async.config.AsyncConfig;
import io.github.linyimin0812.async.utils.BeanDefinitionUtil;
import io.github.linyimin0812.profiler.common.logger.LogFactory;
import io.github.linyimin0812.profiler.common.logger.Logger;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.StandardMethodMetadata;
import org.springframework.util.ClassUtils;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author linyimin
**/
public class AsyncInitBeanFinder {
private static final Logger logger = LogFactory.getAsyncBeanLogger();
public static String getAsyncInitMethodName(String beanName, BeanDefinition beanDefinition) {
if (beanDefinition == null) {
logger.warn(AsyncInitBeanFinder.class, "The beanName: {} of BeanDefinition is not exist!!!", beanName);
return null;
}
if (!AsyncConfig.getInstance().isAsyncBean(beanName)) {
return null;
}
if (BeanDefinitionUtil.isFromConfigurationSource(beanDefinition)) {
return scanAsyncInitMethodOnMethod(beanName, (AnnotatedBeanDefinition) beanDefinition);
} else {
Class> beanClassType = BeanDefinitionUtil.resolveBeanClassType(beanDefinition);
if (beanClassType == null) {
return null;
}
return scanAsyncInitMethodOnClass(beanClassType);
}
}
private static String scanAsyncInitMethodOnClass(Class> beanClassType) {
List candidateMethods = new ArrayList<>();
for (Method method : beanClassType.getDeclaredMethods()) {
List annotations= Arrays.stream(method.getAnnotations()).map(annotation -> annotation.annotationType().getName()).collect(Collectors.toList());
if (annotations.contains("javax.annotation.PostConstruct") || annotations.contains("jakarta.annotation.PostConstruct")) {
candidateMethods.add(method);
}
}
if (candidateMethods.isEmpty()) {
return null;
}
if (candidateMethods.size() == 1) {
return candidateMethods.get(0).getName();
}
logger.warn(AsyncInitBeanFinder.class, "There are {} @PostConstruct methods, async execution is not performed!!!", candidateMethods.size());
return null;
}
private static String scanAsyncInitMethodOnMethod(String beanName, AnnotatedBeanDefinition beanDefinition) {
Class> returnType;
Class> declaringClass;
List candidateMethods = new ArrayList<>();
MethodMetadata methodMetadata = beanDefinition.getFactoryMethodMetadata();
try {
assert methodMetadata != null;
returnType = ClassUtils.forName(methodMetadata.getReturnTypeName(), null);
declaringClass = ClassUtils.forName(methodMetadata.getDeclaringClassName(), null);
} catch (ClassNotFoundException e) {
logger.error(AsyncInitBeanFinder.class, "get returnType and declaringClass error. bean: {}", beanName, e);
return null;
}
if (methodMetadata instanceof StandardMethodMetadata) {
candidateMethods.add(((StandardMethodMetadata) methodMetadata).getIntrospectedMethod());
} else {
for (Method method : declaringClass.getDeclaredMethods()) {
if (!method.getName().equals(methodMetadata.getMethodName()) || !method.getReturnType().getTypeName().equals(methodMetadata.getReturnTypeName())) {
continue;
}
if (!AnnotatedElementUtils.hasAnnotation(method, Bean.class)) {
continue;
}
Bean bean = method.getAnnotation(Bean.class);
Set beanNames = new HashSet<>();
beanNames.add(method.getName());
if (bean != null) {
beanNames.addAll(Arrays.asList(bean.name()));
beanNames.addAll(Arrays.asList(bean.value()));
}
if (!beanNames.contains(beanName)) {
continue;
}
candidateMethods.add(method);
}
}
if (candidateMethods.isEmpty()) {
logger.warn(AsyncInitBeanFinder.class, "The beanName: {} of bean is not exist!!!", beanName);
return null;
}
if (candidateMethods.size() == 1) {
Bean bean = candidateMethods.get(0).getAnnotation(Bean.class);
return bean == null ? null : bean.initMethod();
}
logger.error(AsyncInitBeanFinder.class, "Multi @Bean-method with same name try to publish in {}, async execution is not performed!!!", returnType.getCanonicalName());
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy