Spring的Bean定义注册中心BeanDefinitionRegistry
本文内容纲要:
- 一、BeanDefinitionRegistry- 二、BeanDefinitionRegistry的实现类
- 1、SimpleBeanDefinitionRegistry
- 2 、DefaultListableBeanFactory
- 三、GenericApplicationContext
一、BeanDefinitionRegistry
BeanDefinitionRegistry是一个接口继承AliasRegistry接口(别名处理)
public interface BeanDefinitionRegistry extends AliasRegistry { /** 在这个注册表中注册一个新的bean定义
*/
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
/**
删除给定名称的BeanDefinition*/
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
返回给定bean名称的BeanDefinition*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
检查注册表是否包含给定名称的bean定义*/
boolean containsBeanDefinition(String beanName);
/**
返回该注册表中定义的所有bean的名称*/
String[] getBeanDefinitionNames();
/**
返回注册表中定义的bean定义的数量*/
int getBeanDefinitionCount();
/**
给定的bean名是否已经在这个注册表中使用*/
boolean isBeanNameInUse(String beanName);
}
二、BeanDefinitionRegistry的实现类
1、SimpleBeanDefinitionRegistry
public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry { /** Map of bean definition objects, keyed by bean name. */
//存储bean的定义线程安全
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64);
//注册bean的定义
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "'beanName' must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
this.beanDefinitionMap.put(beanName, beanDefinition);
}
//根据名称删除bean的定义 没有定义抛出异常
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
if (this.beanDefinitionMap.remove(beanName) == null) {
throw new NoSuchBeanDefinitionException(beanName);
}
}
//获取bean的定义
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
//
public boolean containsBeanDefinition(String beanName) {
return this.beanDefinitionMap.containsKey(beanName);
}
//
public String[] getBeanDefinitionNames() {
return StringUtils.toStringArray(this.beanDefinitionMap.keySet());
}
//
public int getBeanDefinitionCount() {
return this.beanDefinitionMap.size();
}
//
public boolean isBeanNameInUse(String beanName) {
return isAlias(beanName) || containsBeanDefinition(beanName);
}
}
2 、DefaultListableBeanFactory
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
...
/** Map of bean definition objects, keyed by bean name */ 存bean的定义 线程安全
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
// 保存所有的Bean名称
/** List of bean definition names, in registration order */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
// 注册Bean定义信息~~
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
...
BeanDefinition oldBeanDefinition = this.beanDefinitionMap.get(beanName);
// 如果不为null,说明这个beanName对应的Bean定义信息已经存在了~~~~~
if (oldBeanDefinition != null) {
// 是否允许覆盖(默认是true 表示允许的)
if (!isAllowBeanDefinitionOverriding()) {
// 抛异常
}
// 若允许覆盖 那还得比较下role 如果新进来的这个Bean的role更大
// 比如老的是ROLE_APPLICATION(0) 新的是ROLE_INFRASTRUCTURE(2)
// 最终会执行到put,但是此处输出一个warn日志,告知你的bean被覆盖啦~~~~~~~(我们自己覆盖Spring框架内的bean显然就不需要warn提示了)
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// 仅仅输出一个logger.warn
}
// 最终会执行put,但是内容还不相同 那就提醒一个info信息吧
else if (!beanDefinition.equals(oldBeanDefinition)) {
// 输出一个info信息
}
else {
// 输出一个debug信息
}
// 最终添加进去 (哪怕已经存在了~)
// 从这里能看出Spring对日志输出的一个优秀处理,方便我们定位问题~~~
this.beanDefinitionMap.put(beanName, beanDefinition);
// 请注意:这里beanName并没有再add了,因为已经存在了 没必要了嘛
}
else {
// hasBeanCreationStarted:表示已经存在bean开始创建了(开始getBean()了吧~~~)
if (hasBeanCreationStarted()) {
// 注册过程需要synchronized,保证数据的一致性 synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition); // 放进去
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
//
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
// 表示仍然在启动 注册的状态~~~就很好处理了 put仅需,名字add进去
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
// 手动注册的BeanNames里面移除~~~ 因为有Bean定义信息了,所以现在不是手动直接注册的Bean单例~~~~
this.manualSingletonNames.remove(beanName);
}
// 这里的意思是:但凡你新增了一个新的Bean定义信息,之前已经冻结的就清空呗~~~
this.frozenBeanDefinitionNames = null;
}
// 最后异步很有意思:老的bean定义信息不为null(beanName已经存在了),或者这个beanName直接是一个单例Bean了~
if (oldBeanDefinition != null || containsSingleton(beanName)) {
// 做清理工作:
// clearMergedBeanDefinition(beanName)
// destroySingleton(beanName); 销毁这个单例Bean 因为有了该bean定义信息 最终还是会创建的
// Reset all bean definitions that have the given bean as parent (recursively). 处理该Bean定义的getParentName 有相同的也得做清楚 所以这里是个递归
resetBeanDefinition(beanName);
}
}
@Override
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
// 移除整体上比较简单:beanDefinitionMap.remove
// beanDefinitionNames.remove
// resetBeanDefinition(beanName);
BeanDefinition bd = this.beanDefinitionMap.remove(beanName);
// 这里发现移除,若这个Bean定义本来就不存在,事抛异常,而不是返回null 需要注意~~~~
if (bd == null) {
throw new NoSuchBeanDefinitionException(beanName);
}
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) {
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames);
updatedDefinitions.remove(beanName);
this.beanDefinitionNames = updatedDefinitions;
}
} else {
this.beanDefinitionNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
resetBeanDefinition(beanName);
}
// 获取bean的定义
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
@Override
public boolean containsBeanDefinition(String beanName) {
return this.beanDefinitionMap.containsKey(beanName);
}
@Override
public int getBeanDefinitionCount() {
return this.beanDefinitionMap.size();
}
@Override
public String[] getBeanDefinitionNames() {
String[] frozenNames = this.frozenBeanDefinitionNames;
if (frozenNames != null) {
return frozenNames.clone();
}
else {
return StringUtils.toStringArray(this.beanDefinitionNames);
}
}
}
三、GenericApplicationContext
1、GenericApplicationContext 的属性
//bean工厂 上面第二个实现类 private final DefaultListableBeanFactory beanFactory;
//读取配置文件
@Nullable
private ResourceLoader resourceLoader;
private boolean customClassLoader = false;
//线程安全 boolean
private final AtomicBoolean refreshed = new AtomicBoolean();
2、手动创建bean
GenericApplicationContext ctx = new GenericApplicationContext(); //手动使用XmlBeanDefinitionReader
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
//加载ClassPathResource
xmlReader.loadBeanDefinitions(new ClassPathResource("spring.xml"));//调用Refresh方法 启动容器
ctx.refresh();
//和其他ApplicationContext方法一样的使用方式 实体类为spring.xml中bean对象
System.out.println(ctx.getBean("person"));
本文内容总结:一、BeanDefinitionRegistry,二、BeanDefinitionRegistry的实现类, 1、SimpleBeanDefinitionRegistry, 2 、DefaultListableBeanFactory,三、GenericApplicationContext,
原文链接:https://www.cnblogs.com/kjcc/p/13692502.html
以上是 Spring的Bean定义注册中心BeanDefinitionRegistry 的全部内容, 来源链接: utcz.com/z/362364.html

