Spring核心BeanDefinition

BeanDifinition

1. 接口类

publicinterfaceBeanDefinitionextendsAttributeAccessor, 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();

voidsetParentName(String parentName);

String getBeanClassName();

voidsetBeanClassName(String beanClassName);

String getFactoryBeanName();

voidsetFactoryBeanName(String factoryBeanName);

String getFactoryMethodName();

voidsetFactoryMethodName(String factoryMethodName);

String getScope();

voidsetScope(String scope);

booleanisLazyInit();

voidsetLazyInit(boolean lazyInit);

String[] getDependsOn();

voidsetDependsOn(String... dependsOn);

booleanisAutowireCandidate();

voidsetAutowireCandidate(boolean autowireCandidate);

booleanisPrimary();

voidsetPrimary(boolean primary);

ConstructorArgumentValues getConstructorArgumentValues();

MutablePropertyValues getPropertyValues();

booleanisSingleton();

booleanisPrototype();

booleanisAbstract();

intgetRole();

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的公共配置项的存储就需要借助此接口来存储

BeanMetadataElement 可以获取bean元数据的配置源

AbstractBeanDefinition

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

RootBeanDefinition

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

ChildBeanDefinition

子bean定义,必须有父bean定义,其他完全是抽象类的功能实现

GenericBeanDefinition

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

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

java中的继承关系是通过extends关键字进行关联

spring中可以通过xml配置parent进行继承置项

<!-- 父子bean 测试xml -->

<beanid="parent"abstract="true">   

<propertyname="name"value="爹"></property>

</bean>

<beanid="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 {

thrownew NoSuchBeanDefinitionException(bd.getParentName(),

"Parent name '" + bd.getParentName() + "' is equal to bean name '" + beanName +

"': cannot be resolved without an AbstractBeanFactory parent");

}

}

}

catch (NoSuchBeanDefinitionException ex) {

thrownew 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

以上是 Spring核心BeanDefinition 的全部内容, 来源链接: utcz.com/a/23362.html

回到顶部