Spring之核心BeanDefinition

BeanDifinitionjava

1. 接口类

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

	String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

	int ROLE_APPLICATION = 0;

	int ROLE_SUPPORT = 1;

	int ROLE_INFRASTRUCTURE = 2;

	String getParentName();

	void setParentName(String parentName);

	String getBeanClassName();

	void setBeanClassName(String beanClassName);

	String getFactoryBeanName();

	void setFactoryBeanName(String factoryBeanName);

	
	String getFactoryMethodName();

	void setFactoryMethodName(String factoryMethodName);

	String getScope();

	void setScope(String scope);

	boolean isLazyInit();


	void setLazyInit(boolean lazyInit);

	String[] getDependsOn();

	void setDependsOn(String... dependsOn);

	boolean isAutowireCandidate();

	void setAutowireCandidate(boolean autowireCandidate);


	boolean isPrimary();


	void setPrimary(boolean primary);


	ConstructorArgumentValues getConstructorArgumentValues();

	
	MutablePropertyValues getPropertyValues();


	boolean isSingleton();

	boolean isPrototype();

	boolean isAbstract();

	int getRole();

	String getDescription();

	String getResourceDescription();


	BeanDefinition getOriginatingBeanDefinition();

}

复制代码

2.BeanDefinition是描述bean元数据定义信息的接口定义

接口能够获得bean的Class,bean的做用域、是否为懒加载、依赖的bean、构造参数、属性值等
能够想象咱们在xml配置的bean属性等确定性须要封装存储在一个地方,那么BeanDefinition就是封装bean属性的定义。在java中咱们全部的类定义都是在class文件中,经过jvm加载。在spring中就是经过xml或者注解定义,转化为BeanDefinition定义,经过spring ioc模块生成具体的bean

3.实现类结构图

BeanDefinition

BeanDefinition接口继承了两个接口AttributeAccessor、BeanMetadataElement, 从名字能够看出

AttributeAccessor是属性存储器,一些非bean的公共配置项的存储就须要借助此接口来存储spring

BeanMetadataElement 能够获取bean元数据的配置源dom

AbstractBeanDefinition

是BeanDefinition的抽象实现,其实已经基本实现了所有功能,继承了BeanMetadataAttributeAccessor, 此类是前面两个接口的具体实现,这样赋予了AbstractBeanDefinition两个接口的真正能力

RootBeanDefinition

是一个根bean定义,它不能有父bean定义。父子定义是spring的bean配置的一个继承关系

ChildBeanDefinition

子bean定义,必须有父bean定义,其余彻底是抽象类的功能实现

GenericBeanDefinition

通用的bean定义实现,也是目前默认建立的实现

4.spring中父子bean配置继承关系

java中的继承关系是经过extends关键字进行关联
spring中能够经过xml配置parent进行继承置项
<!-- 父子bean 测试xml -->
    <bean id="parent" abstract="true">    
        <property name="name" value="爹"></property>
    </bean>

    <bean id="child" parent="parent" lass="spring.domain.Bean">
    </bean>

复制代码
ClassPathXmlApplicationContext cpa = new ClassPathXmlApplicationContext("/spring/spring-config.xml");
        cpa.refresh();

        System.out.println(JSON.toJSONString(cpa.getBean("child")));
        cpa.destroy();
复制代码
运行后能够发现child的bean 其中的name属性是爹,child继承了parent的配置属性

源码观察

// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					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(beanName);
					}
				}
				else {
					getBean(beanName);
				}
			}
		}
复制代码
preInstantiateSingletons开始触发生成bean方法时,遍历全部beanNames,对于每个beanName都须要经过#getMergedLocalBeanDefinition 方法来拿到最终的BeanDefinition, 这个方法作了什么呢?
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)) {
							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.
                 // 先生成一个父类属性的Root,再用子类属性覆盖
					mbd = new RootBeanDefinition(pbd);
					mbd.overrideFrom(bd);
				}

				// Set default singleton scope, if not configured before.
				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;
		}
	}
复制代码
能够看到根据beanDefinition中的parentName获取到父BeanDefinition,递归获取,而且子类覆盖父类,最终获得一个全部配置项合并的BeanDefinition, 用这个RootBeanDefinition进行初始化bean
相关文章
相关标签/搜索