主页 > IT业界  > 

getMergedLocalBeanDefinition方法的作用

getMergedLocalBeanDefinition方法的作用

### 该方法说明

先说总结作用,该方法的作用就是在xml 文件中通过parent属性与指定的类进行绑定,当调用getMergedLocalBeanDefinition 方法时将parent指定的bean定义对象与当前bean定义对象合并,将合并的对象放入mergedBeanDefinitions这个集合中

```java private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256); ```

从名称上来看是合并的bean 定义对象,刚开始看的我一直不明白这个集合的作用,之后我了解到**Spring 允许通过配置让一个 Bean 定义继承另一个 Bean 定义**。例如我们要配置两个不同的数据库,分别是使用了不同的密码和账号,但是某些属性上是相同的通常我们会有如下配置:

```xml <bean id="dataSource1" class="com.zaxxer.hikari.HikariDataSource">     <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db1"/>     <property name="username" value="user1"/>     <property name="password" value="pass1"/>     <property name="maximumPoolSize" value="20"/>     <property name="minimumIdle" value="5"/> </bean>

<bean id="dataSource2" class="com.zaxxer.hikari.HikariDataSource">     <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db2"/>     <property name="username" value="user2"/>     <property name="password" value="pass2"/>     <property name="maximumPoolSize" value="20"/>     <property name="minimumIdle" value="5"/> </bean> ```

spring 为了简化这个配置允许我们使用parent 属性实现bean定义的继承

```xml <bean id="parentDataSource" class="com.zaxxer.hikari.HikariDataSource" abstract="true">     <property name="maximumPoolSize" value="20"/>     <property name="minimumIdle" value="5"/> </bean>

<bean id="dataSource1" class="com.zaxxer.hikari.HikariDataSource" parent="parentDataSource">     <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db1"/>     <property name="username" value="user1"/>     <property name="password" value="pass1"/> </bean>

<bean id="dataSource2" class="com.zaxxer.hikari.HikariDataSource" parent="parentDataSource">     <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db2"/>     <property name="username" value="user2"/>     <property name="password" value="pass2"/> </bean> ```

<br/>

### 源码讲解

而通过getMergedLocalBeanDefinition 方法将会将这些bean定义的对象合并,具体代码如下,首先尝试从已合并的Bean定义对象集合中获取,如果能获取到直接返回否则尝试合并bean定义对象:

```java // Quick check on the concurrent map first, with minimal locking. // 先通过mergedBeanDefinitions获取Bean 对象 RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null && !mbd.stale) {     return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); ```

getMergedBeanDefinition方法首先调用了当前方法的重写方法:

```java protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)         throws BeanDefinitionStoreException {

    return getMergedBeanDefinition(beanName, bd, null); } ```

首先锁定了bean定义集合对象

``` synchronized (this.mergedBeanDefinitions) ```

由于containingBd对象传入的是一个null,所以这段代码忽略掉:

```java if (containingBd == null) {      mbd = this.mergedBeanDefinitions.get(beanName); } ```

主要核心代码在这块,首先判断parentName是否为空:

```java if (bd.getParentName() == null) ```

如果为空,表示不需要合并,直接创建一个 RootBeanDefinition对象:

```java if (bd.getParentName() == null) {     if (bd instanceof RootBeanDefinition rootBeanDef) {       // cloneBeanDefinition方法是new RootBeanDefinition(this)       // 相当于创建了一个根节点对象         mbd = rootBeanDef.cloneBeanDefinition();     } else {                mbd = new RootBeanDefinition(bd);     } } ```

否则通过getMergedBeanDefinition(parentBeanName)方法获取parent属性的对象

```java String parentBeanName = transformedBeanName(bd.getParentName()); if (!beanName.equals(parentBeanName)) {     pbd = getMergedBeanDefinition(parentBeanName); } ```

然后覆盖相关属性:

```java mbd = new RootBeanDefinition(pbd); mbd.overrideFrom(bd); ```

mbd = new RootBeanDefinition(pbd);这段代码的具体内容如下,其实就是将parent的bean定义对象的属性覆盖到子bean定义对象当中:

```java setParentName(original.getParentName()); setBeanClassName(original.getBeanClassName()); setScope(original.getScope()); setAbstract(original.isAbstract()); setFactoryBeanName(original.getFactoryBeanName()); setFactoryMethodName(original.getFactoryMethodName()); setRole(original.getRole()); setSource(original.getSource()); copyAttributesFrom(original);

if (original instanceof AbstractBeanDefinition originalAbd) {     if (originalAbd.hasBeanClass()) {         setBeanClass(originalAbd.getBeanClass());     }     if (originalAbd.hasConstructorArgumentValues()) {         setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));     }     if (originalAbd.hasPropertyValues()) {         setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));     }     if (originalAbd.hasMethodOverrides()) {         setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides()));     }     Boolean lazyInit = originalAbd.getLazyInit();     if (lazyInit != null) {         setLazyInit(lazyInit);     }     setAutowireMode(originalAbd.getAutowireMode());     setDependencyCheck(originalAbd.getDependencyCheck());     setDependsOn(originalAbd.getDependsOn());     setAutowireCandidate(originalAbd.isAutowireCandidate());     setPrimary(originalAbd.isPrimary());     copyQualifiersFrom(originalAbd);     setInstanceSupplier(originalAbd.getInstanceSupplier());     setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed());     setLenientConstructorResolution(originalAbd.isLenientConstructorResolution());     setInitMethodNames(originalAbd.getInitMethodNames());     setEnforceInitMethod(originalAbd.isEnforceInitMethod());     setDestroyMethodNames(originalAbd.getDestroyMethodNames());     setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod());     setSynthetic(originalAbd.isSynthetic());     setResource(originalAbd.getResource()); ```

最后列出该方法的所有内容:

```java     protected RootBeanDefinition getMergedBeanDefinition(             String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)             throws BeanDefinitionStoreException {

        synchronized (this.mergedBeanDefinitions) {             RootBeanDefinition mbd = null;             RootBeanDefinition previous = null;

            // Check with full lock now in order to enforce the same merged instance.             if (containingBd == null) {                 mbd = this.mergedBeanDefinitions.get(beanName);             }

            if (mbd == null || mbd.stale) {                 previous = mbd;                 if (bd.getParentName() == null) {                     // Use copy of given root bean definition.                     if (bd instanceof RootBeanDefinition rootBeanDef) {                         mbd = rootBeanDef.cloneBeanDefinition();                     }                     else {                         mbd = new RootBeanDefinition(bd);                     }                 }                 else {                     // Child bean definition: needs to be merged with parent.                     BeanDefinition pbd;                     try {                         String parentBeanName = transformedBeanName(bd.getParentName());                         if (!beanName.equals(parentBeanName)) {                             pbd = getMergedBeanDefinition(parentBeanName);                         }                         else {                             if (getParentBeanFactory() instanceof ConfigurableBeanFactory parent) {                                 pbd = parent.getMergedBeanDefinition(parentBeanName);                             }                             else {                                 throw new NoSuchBeanDefinitionException(parentBeanName,                                         "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +                                                 "': cannot be resolved without a ConfigurableBeanFactory parent");                             }                         }                     }                     catch (NoSuchBeanDefinitionException ex) {                         throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,                                 "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);                     }                     // Deep copy with overridden values.                     mbd = new RootBeanDefinition(pbd);                     mbd.overrideFrom(bd);                 }

                // Set default singleton scope, if not configured before.                 if (!StringUtils.hasLength(mbd.getScope())) {                     mbd.setScope(SCOPE_SINGLETON);                 }

                // A bean contained in a non-singleton bean cannot be a singleton itself.                 // Let's correct this on the fly here, since this might be the result of                 // parent-child merging for the outer bean, in which case the original inner bean                 // definition will not have inherited the merged outer bean's singleton status.                 if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {                     mbd.setScope(containingBd.getScope());                 }

                // Cache the merged bean definition for the time being                 // (it might still get re-merged later on in order to pick up metadata changes)                 if (containingBd == null && isCacheBeanMetadata()) {                     this.mergedBeanDefinitions.put(beanName, mbd);                 }             }             if (previous != null) {                 copyRelevantMergedBeanDefinitionCaches(previous, mbd);             }             return mbd;         }     } ```

标签:

getMergedLocalBeanDefinition方法的作用由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“getMergedLocalBeanDefinition方法的作用