io.github.xiejx618.replace.ReplaceBeanPostProcessor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of replace-bean-boot-starter Show documentation
Show all versions of replace-bean-boot-starter Show documentation
Implement the function of replacing spring beans.
The newest version!
package io.github.xiejx618.replace;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.util.*;
import java.beans.Introspector;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* 处理所有Bean实例化前先检查是否有替换bean配置.如果有,就做替换.
*/
public class ReplaceBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
private static final String SCOPED_PROXY_FACTORY_BEAN = "org.springframework.aop.scope.ScopedProxyFactoryBean";
private static final Map replaceMap = new HashMap<>();
private final ConfigurableBeanFactory beanFactory;
public ReplaceBeanPostProcessor(ConfigurableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
//如果bean经过了scope代理,就取原beanName替换信息
ReplaceInfo replaceInfo = replaceMap.get(ScopedProxyUtils.isScopedTarget(beanName) ?
ScopedProxyUtils.getOriginalBeanName(beanName) : beanName);
if (replaceInfo == null) {
return null;
}
BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
//排除ScopedProxyFactoryBean替换
if (SCOPED_PROXY_FACTORY_BEAN.equals(beanDefinition.getBeanClassName())) {
return null;
}
Method method = replaceInfo.getMethod();
Object factory = replaceInfo.getFactory();
String clazz = replaceInfo.getClazz();
if (method != null && factory != null) {
//通过工厂方法直接生成实例
if (beanDefinition instanceof AbstractBeanDefinition) {
Supplier> instanceSupplier = () -> ReflectionUtils.invokeMethod(method, factory);
((AbstractBeanDefinition) beanDefinition).setInstanceSupplier(instanceSupplier);
} else {
throw new IllegalStateException("不支持的BeanDefinition类型:" + beanDefinition.getClass());
}
} else if (StringUtils.hasText(clazz)) {
//通过beanClass反射生成实例
beanDefinition.setBeanClassName(clazz);
if (beanDefinition instanceof AbstractBeanDefinition) {
//为了兼容spring aot,强制不使用InstanceSupplier
((AbstractBeanDefinition) beanDefinition).setInstanceSupplier(null);
}
} else {
throw new IllegalStateException("method和clazz为空,替换失败");
}
replaceInfo.replaced = true;
return null;
}
/**
* 通过工厂方法注册
*
* @param context 上下文
* @param factories 来源工厂实例
*/
public static void registerFromFactory(ConfigurableApplicationContext context, List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy