Spring源码深度解析(郝佳)-学习-源码解析-abstract-bean

20 篇文章 1 订阅
18 篇文章 0 订阅

这里我们首先来讲抽象 bean如何解析及实现属性的继承的
先上示例。

Car.java

@Data
public class Car {
    private String brand;
    private int maxSpeed;
    private String color;
}

spring27_abstract_bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">



    <!--所以声明为 abstract = "true" 表示这个<bean> 不实例化为一个对应的 bean , 在代码清单中,如果用户没有指定
    abstract="true ", Spring ioc 容器将实例化一个名为 abstractCar 的 bean
    -->
    <bean id="abstract" class="com.spring_1_100.test_21_30.test27_abstract_bean.Car"
          p:maxSpeed="300" abstract="true"></bean>

    <bean id="abstractCar" class="com.spring_1_100.test_21_30.test27_abstract_bean.Car"
    p:brand="红旗 CA72" abstract="true" parent="abstract"></bean>

    <bean id="car4" p:color="黑色" parent="abstractCar"></bean>

</beans>

Test27.java

public class Test27 {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring_1_100/config_21_30/spring27_abstract_bean.xml");
        Car car =(Car) ac.getBean("car4");
        System.out.println(JSON.toJSONString(car));
    }
}

结果输出
在这里插入图片描述

首先我们来看 bean 的解析。

parent:标签解析

public static AbstractBeanDefinition createBeanDefinition(
		String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException {

	GenericBeanDefinition bd = new GenericBeanDefinition();
	// parentName 可能为空
	bd.setParentName(parentName);
	if (className != null) {
		if (classLoader != null) {
			// 如果classLoader不为空。则使用传入的classLoader同一虚拟机
			// 记录className
			bd.setBeanClass(ClassUtils.forName(className, classLoader));
		}
		else {
			bd.setBeanClassName(className);
		}
	}
	return bd;
}

abstract的解析:

public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
                                                            BeanDefinition containingBean, AbstractBeanDefinition bd) {
    // 解析scope 属性
    if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
        error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
    } else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
        bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
    } else if (containingBean != null) {
        // Take default from containing bean in case of an inner bean definition.
        // 在嵌入beanDefinition的情况下且没有单独指定scope的属性则使用父类默认的
        bd.setScope(containingBean.getScope());
    }
    //解析abstract属性
    if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
        bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
    }

    // 解析lazy-init属性
    String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
    if (DEFAULT_VALUE.equals(lazyInit)) {
        lazyInit = this.defaults.getLazyInit();
    }
    //若没有设置或者设置其他的字符会被设置为false
    bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
    //解析autowire属性
    String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
    bd.setAutowireMode(getAutowireMode(autowire));
    // 解析dependency-check属性
    String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
    bd.setDependencyCheck(getDependencyCheck(dependencyCheck));
    //解析depends-on属性
    if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
        String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
        bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
    }
    //解析autowire-candidate属性
    String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
    if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
        String candidatePattern = this.defaults.getAutowireCandidates();
        if (candidatePattern != null) {
            String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
            bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
        }
    } else {
        bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
    }
    //解析primary属性
    if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
        bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
    }
    //解析init-method属性
    if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
        String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
        if (!"".equals(initMethodName)) {
            bd.setInitMethodName(initMethodName);
        }
    } else {
        if (this.defaults.getInitMethod() != null) {
            bd.setInitMethodName(this.defaults.getInitMethod());
            bd.setEnforceInitMethod(false);
        }
    }
    //解析destroy-method属性
    if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
        String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
        bd.setDestroyMethodName(destroyMethodName);
    } else {
        if (this.defaults.getDestroyMethod() != null) {
            bd.setDestroyMethodName(this.defaults.getDestroyMethod());
            bd.setEnforceDestroyMethod(false);
        }
    }
    // 解析factory-method属性
    if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
        bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
    }
    // 解析factory-bean属性
    if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
        bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
    }

    return bd;
}

而对于普通的属性 p:color 的解析将在SimplePropertyNamespaceHandler中进行解析
在这里插入图片描述

public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
	if (node instanceof Attr) {
		Attr attr = (Attr) node;
		String propertyName = parserContext.getDelegate().getLocalName(attr);
		String propertyValue = attr.getValue();
		MutablePropertyValues pvs = definition.getBeanDefinition().getPropertyValues();
		if (pvs.contains(propertyName)) {
			parserContext.getReaderContext().error("Property '" + propertyName + "' is already defined using " +
					"both  and inline syntax. Only one approach may be used per property.", attr);
		}
		if (propertyName.endsWith(REF_SUFFIX)) {
			propertyName = propertyName.substring(0, propertyName.length() - REF_SUFFIX.length());
			pvs.add(Conventions.attributeNameToPropertyName(propertyName), new RuntimeBeanReference(propertyValue));
		}
		else {
			pvs.add(Conventions.attributeNameToPropertyName(propertyName), propertyValue);
		}
	}
	return definition;
}

最终保存到BeanDefinition 的MutablePropertyValues中。

Bean 的初始化和依赖注入,这样当应用程序第一次向容器索取所需要的Bean时,容器不再需要对Bean进行初始化的依赖注入可直接从已经完成的实例化和依赖注入的Bean中取一个现在的Bean ,提高第一次获取Bean的性能

DefaultListableBeanFactory.java

@Override
  public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isDebugEnabled()) {
      this.logger.debug("Pre-instantiating singletons in " + this);
    }
    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
      // 获取指定名称的Bean 定义
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      // Bean 不是抽象的,是单例模式的,且lazy-init属性配置为false
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
        // 如果指定的名称的Bean是创建容器的Bean
        if (isFactoryBean(beanName)) {
          // FACTORY_BEAN_PREFIX="&",当Bean 名称前面加了&符号时,获取的是容器对象本身,而不是容器产生的Bean
          // 调用getBean 方法,触发Bean实例化,和依赖注入
          final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
          // 标识是否需要预实例化
          boolean isEagerInit;
          if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
            // 一个匿名的内部类
            isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
              @Override
              public Boolean run() {
                return ((SmartFactoryBean<?>) factory).isEagerInit();
              }
            }, getAccessControlContext());
          }
          else {
            isEagerInit = (factory instanceof SmartFactoryBean &&
                ((SmartFactoryBean<?>) factory).isEagerInit());
          }
          if (isEagerInit) {
            // 调用getBean()方法,触发Bean实例化和依赖注入
            getBean(beanName);
          }
        }
        else {
          getBean(beanName);
        }
      }
    }

    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
        final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
        if (System.getSecurityManager() != null) {
          AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
              smartSingleton.afterSingletonsInstantiated();
              return null;
            }
          }, getAccessControlContext());
        }
        else {
          smartSingleton.afterSingletonsInstantiated();
        }
      }
    }
  }
  

因此,在创建过程中,对于抽象类,不会被创建,而对于普通的类,如果填充了 parent 属性,则会从父类中继承 BeanDefinition 中的属性。

AbstractBeanFactory.java

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
	RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
	if (mbd != null) {
		return mbd;
	}
	return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
  

AbstractBeanFactory.java

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

	return getMergedBeanDefinition(beanName, bd, null);
}

AbstractBeanFactory.java

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

	synchronized (this.mergedBeanDefinitions) {
		RootBeanDefinition mbd = 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) {
			if (bd.getParentName() == null) {
				// Use copy of given root bean definition.
				if (bd instanceof RootBeanDefinition) {
					mbd = ((RootBeanDefinition) bd).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)) {
						//如果配置了 parent ,则反复的调用 BeanDefinition的合并方法
						pbd = getMergedBeanDefinition(parentBeanName);
					}
					else {
						if (getParentBeanFactory() instanceof ConfigurableBeanFactory) {
							pbd = ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(parentBeanName);
						}
						else {
							throw new NoSuchBeanDefinitionException(bd.getParentName(),
									"Parent name '" + bd.getParentName() + "' is equal to bean name '" + beanName +
									"': cannot be resolved without an AbstractBeanFactory 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父亲的BeanDefinition, bd子的 beanDefinition
				mbd.overrideFrom(bd);
			}

			// Set default singleton scope, if not configured before.
			其他的属性是子 BeanDefinition 覆盖父 BeanDefinition,而只有 Scope属性,被父亲保留
			if (!StringUtils.hasLength(mbd.getScope())) {
				mbd.setScope(RootBeanDefinition.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());
			}

			// Only cache the merged bean definition if we're already about to create an
			// instance of the bean, or at least have already created an instance before.
			if (containingBd == null && isCacheBeanMetadata()) {
				this.mergedBeanDefinitions.put(beanName, mbd);
			}
		}
		return mbd;
	}
}

AbstractBeanDefinition.java

public void overrideFrom(BeanDefinition other) {
	//复制子类的 beanClassName	
	if (StringUtils.hasLength(other.getBeanClassName())) {
		setBeanClassName(other.getBeanClassName());
	}
	//复制子类FactoryBeanName	
	if (StringUtils.hasLength(other.getFactoryBeanName())) {
		setFactoryBeanName(other.getFactoryBeanName());
	}
	//复制子类FactoryMethodName	
	if (StringUtils.hasLength(other.getFactoryMethodName())) {
		setFactoryMethodName(other.getFactoryMethodName());
	}
	//复制子类Scope 属性	
	if (StringUtils.hasLength(other.getScope())) {
		setScope(other.getScope());
	}
	//复制子类Abstract 属性	
	setAbstract(other.isAbstract());
	//复制子类lazyInit	
	setLazyInit(other.isLazyInit());
	setRole(other.getRole());
	//复制子类构造函数参数getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
	//复制子类属性参数
	getPropertyValues().addPropertyValues(other.getPropertyValues());
	setSource(other.getSource());
	copyAttributesFrom(other);

	if (other instanceof AbstractBeanDefinition) {
		AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;
		if (otherAbd.hasBeanClass()) {
			setBeanClass(otherAbd.getBeanClass());
		}
		setAutowireCandidate(otherAbd.isAutowireCandidate());
		setAutowireMode(otherAbd.getAutowireMode());
		copyQualifiersFrom(otherAbd);
		setPrimary(otherAbd.isPrimary());
		setDependencyCheck(otherAbd.getDependencyCheck());
		setDependsOn(otherAbd.getDependsOn());
		setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
		setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
		if (StringUtils.hasLength(otherAbd.getInitMethodName())) {
			setInitMethodName(otherAbd.getInitMethodName());
			setEnforceInitMethod(otherAbd.isEnforceInitMethod());
		}
		if (otherAbd.getDestroyMethodName() != null) {
			setDestroyMethodName(otherAbd.getDestroyMethodName());
			setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
		}
		getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
		setSynthetic(otherAbd.isSynthetic());
		setResource(otherAbd.getResource());
	}
	else {
		setResourceDescription(other.getResourceDescription());
	}
}

这个方法主要是将子BeanDefinition 覆盖父的 BeanDefinition,重而得到全新的 BeanDefinition定义。并且递归调用。在本例中,先用 car4的 BeanDefinition 覆盖掉 abstractCar 的 BeanDefinition,再用新的 beanDefinition 覆盖掉 abstract 的 BeanDefinition,最终得到合并的 beanDefinition 作为 car4 的 BeanDefinition,因此,car4 有了 abstractCar 配置的 brand 属性,有 abstract 配置的 maxSpeed 属性、
而 abstract 类在 Spring 中是不会被实例化的,因此,在配置的 bean 中,只有 car4最终被实例化,并且有从父类继承而来的属性 brand 和 maxSpeed 属性。

总结 :
在本例中,其实不是非常的复杂,在理解 beanDefinition 的合并是,需要注意一下,子类继承父类,其实就是子类的属性覆盖掉父类的属性,而得到的一个超级类。不过还是那句话,学习源码,一定要自己调试。

本文的 github地址是https://github.com/quyixiao/spring_tiny/tree/master/src/main/java/com/spring_1_100/test_21_30/test27_abstract_bean

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值