spring源码系列一(BeanDefinition)

BeanDefinition顾名思义就是对bean抽象的一个接口定义,看一下有定义了啥东西大家就明白了,

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

 /**
 * 这两个参数应该一看就明白了,singleton和prototype,这个可以看出spring默认提供这两种模式
 * @see #setScope
 */
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; 
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

 //Bean角色
int ROLE_APPLICATION = 0; 
int ROLE_SUPPORT = 1; 
int ROLE_INFRASTRUCTURE = 2;

// 返回/设置父BeanDefinition 
String getParentName(); 
void setParentName(String parentName);

//返回/设置 当前的BeanClassName(不等于最终Bean的名称)
String getBeanClassName(); 
void setBeanClassName(String beanClassName);

//返回设置 factory bean name  
String getFactoryBeanName(); 
void setFactoryBeanName(String factoryBeanName);

String getFactoryMethodName(); 
void setFactoryMethodName(String factoryMethodName);

String getScope(); 

/**

  • 重写bean定义的作用域,对应xml中的 scope=“session”

  • @see #SCOPE_SINGLETON

  • @see #SCOPE_PROTOTYPE
    /
    void setScope(String scope);
    /
    *

  • 返回bean是否为懒加载模式,不能用于在启动过程中的懒加载初始化,仅仅可以用于单例bean。
    /
    boolean isLazyInit();
    void setLazyInit(boolean lazyInit);
    /
    *

  • 设置此bean依赖于初始化的bean的名称。

  • bean factory将确保这些bean首先被初始化。
    */
    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();

}
总结就是提供了父beanname,bean类型名,作用域,懒加载, bean依赖,自动注入候选bean,自动注入候选主要bean熟悉的设置与获取操作。同时提供了判断bean是否为单例、原型模式、抽象bean的操作,及获取bean的描述,资源描述,属性源,构造参数,原始bean定义等操作。

然后我们看一下BeanDefinition实现类,在这里插入图片描述
先看AnnotatedBeanDefinition这个也是个接口

public interface AnnotatedBeanDefinition extends BeanDefinition {

/**
 * Obtain the annotation metadata (as well as basic class metadata)
 * for this bean definition's bean class.
 * @return the annotation metadata object (never {@code null})
 */
AnnotationMetadata getMetadata();

/**
 * Obtain metadata for this bean definition's factory method, if any.
 * @return the factory method metadata, or {@code null} if none
 * @since 4.1.1
 */
@Nullable
MethodMetadata getFactoryMethodMetadata();

}
依靠 AnnotationMetadata 接口判断是否存在指定元注解。所以ScannedGenericBeanDefinition、ConfigurationClassBeanDefinition、AnnotatedGenericBeanDefinition这个几个都关于注解的定义。

ScannedGenericBeanDefinition:存储@Component、@Service、@Controller等注解注释的类
ConfigurationClassBeanDefinition 在@Configuration注解的类中,使用@Bean注解实例化的Bean,其定义会用ConfigurationClassBeanDefinition存储
AnnotatedGenericBeanDefinition:存储@Bean注解注释的类

接下来看
AbstractBeanDefinition
这个抽象类的构造方法设置了BeanDefinition的默认属性,重写了equals,hashCode,toString方法。
ChildBeanDefinition
可以从父BeanDefinition中集成构造方法,属性等
RootBeanDefinition
代表一个从配置源(XML,Java Config等)中生成的BeanDefinition
GenericBeanDefinition
GenericBeanDefinition是自2.5以后新加入的bean文件配置属性定义类,是ChildBeanDefinition和RootBeanDefinition更好的替代者
然后我们在看这个结构就明白这几个的关系了
在这里插入图片描述
BeanDefintion是管理到一个线程安全的Map里面,源码如下:
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {

	Assert.hasText(beanName, "Bean name must not be empty");
	Assert.notNull(beanDefinition, "BeanDefinition must not be null");

	if (beanDefinition instanceof AbstractBeanDefinition) {
		try {
			((AbstractBeanDefinition) beanDefinition).validate();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
					"Validation of bean definition failed", ex);
		}
	}
 //检查是否有相同名字的BeanDefinition已经在IOC容器中注册了
//如果有相同名字的BeanDefinition,但又不允许覆盖,那么会抛出异常
	BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
	if (existingDefinition != null) {
		if (!isAllowBeanDefinitionOverriding()) {
			throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
		}
		else if (existingDefinition.getRole() < beanDefinition.getRole()) {
			// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
			if (logger.isInfoEnabled()) {
				logger.info("Overriding user-defined bean definition for bean '" + beanName +
						"' with a framework-generated bean definition: replacing [" +
						existingDefinition + "] with [" + beanDefinition + "]");
			}
		}
		else if (!beanDefinition.equals(existingDefinition)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Overriding bean definition for bean '" + beanName +
						"' with a different definition: replacing [" + existingDefinition +
						"] with [" + beanDefinition + "]");
			}
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("Overriding bean definition for bean '" + beanName +
						"' with an equivalent definition: replacing [" + existingDefinition +
						"] with [" + beanDefinition + "]");
			}
		}
		**this.beanDefinitionMap.put(beanName, beanDefinition);**
	}
	else {
		if (hasBeanCreationStarted()) {
			// Cannot modify startup-time collection elements anymore (for stable iteration)
			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;
				removeManualSingletonName(beanName);
			}
		}
		else {
			// Still in startup registration phase
			this.beanDefinitionMap.put(beanName, beanDefinition);
			this.beanDefinitionNames.add(beanName);
			removeManualSingletonName(beanName);
		}
		this.frozenBeanDefinitionNames = null;
	}

	if (existingDefinition != null || containsSingleton(beanName)) {
		resetBeanDefinition(beanName);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值