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

回到顶部