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