几个关键点需要知道
本文不谈原理,直接上实战。
几个关键点:如何拿到Spring上下文来创建bean或移除bean?如何准备构建bean所需的BeanDefinition?
第一问:可注入bean工厂org.springframework.beans.factory.support.DefaultListableBeanFactory得到;
第二问:使用org.springframework.beans.factory.support.BeanDefinitionBuilder来构建BeanDefinition。
实例
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.stereotype.Component;
import java.beans.Introspector;
import java.lang.reflect.Modifier;
/**
* Bean 处理器
*/
@Slf4j
@Component
public class SpringBeanClassHandler {
/**
* Bean 工厂
*/
private final DefaultListableBeanFactory beanFactory;
public SpringBeanClassHandler(DefaultListableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
/**
* 注册一个普通的bean
*
* @param beanCls - 待注册的bean class
*/
public void registerBean(Class<?> beanCls) {
if (beanCls == null) {
return;
}
if (Modifier.isAbstract(beanCls.getModifiers())
|| Modifier.isPrivate(beanCls.getModifiers())
|| Modifier.isNative(beanCls.getModifiers())
|| Modifier.isInterface(beanCls.getModifiers())) {
log.warn("can not support register this class to bean for: {} - {}", beanCls.getName(), Modifier.toString(beanCls.getModifiers()));
}
// 注册新的Bean
String beanName = Introspector.decapitalize(beanCls.getSimpleName());
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanCls);
GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);// 按类型自动注入
beanFactory.registerBeanDefinition(beanName, definition);
log.info("dynamic successfully register bean: {}", beanFactory.getBean(beanName));
}
/**
* 移除 Bean
*
* @param beanCls - Bean class
*/
public void removeBean(Class<?> beanCls) {
if (beanCls == null) {
return;
}
String clsName = Introspector.decapitalize(beanCls.getSimpleName());
if (beanFactory.containsBean(clsName)) {
beanFactory.removeBeanDefinition(clsName);
}
}
/**
* Spring 容器是否 已存在Bean
*
* @param beanCls
* @return - boolean
*/
public boolean containsBean(Class<?> beanCls) {
return beanFactory.containsBean(Introspector.decapitalize(beanCls.getSimpleName()));
}
}
完结。