1 先看BeanDefinition的源码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.beans.factory.config;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.AttributeAccessor;
import org.springframework.lang.Nullable;
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype";
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
void setParentName(@Nullable String var1);
@Nullable
String getParentName();
void setBeanClassName(@Nullable String var1);
@Nullable
String getBeanClassName();
void setScope(@Nullable String var1);
@Nullable
String getScope();
void setLazyInit(boolean var1);
boolean isLazyInit();
void setDependsOn(@Nullable String... var1);
@Nullable
String[] getDependsOn();
void setAutowireCandidate(boolean var1);
boolean isAutowireCandidate();
void setPrimary(boolean var1);
boolean isPrimary();
void setFactoryBeanName(@Nullable String var1);
@Nullable
String getFactoryBeanName();
void setFactoryMethodName(@Nullable String var1);
@Nullable
String getFactoryMethodName();
ConstructorArgumentValues getConstructorArgumentValues();
default boolean hasConstructorArgumentValues() {
return !this.getConstructorArgumentValues().isEmpty();
}
MutablePropertyValues getPropertyValues();
default boolean hasPropertyValues() {
return !this.getPropertyValues().isEmpty();
}
boolean isSingleton();
boolean isPrototype();
boolean isAbstract();
int getRole();
@Nullable
String getDescription();
@Nullable
String getResourceDescription();
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
2 什么是BeanDefinition
- BeanDefinition即bean定义,Spring把xml中定义的bean(或者使用@Configuration注解的类中又使用了@Bean注解的方法所
返回的类,还有使用诸如Service、Component等注解标识的类)解析成BeanDefinition,BeanDefinition存放的属性信息
有:class、scope、autowireMode、lazyInit、abstractFlag、dependsOn、constructorArgumentValues等等。
- 从BeanDefinition源码中可以看出,BeanDefinition继承了AttributeAccessor,说明它具有处理属性的能力;
BeanDefinition继承了BeanMetadataElement,说明它可以持有Bean元数据元素,作用是可以持有XML文件的一个bean标签
对应的Object。
3 BeanDefinition存放在哪里
Spring把BeanDefinition作为value、把beanName(我们不明确指定的情况下,Spring会自动为注册的Bean生成一个唯一的
beanName,beanName的生成使用的是BeanNameGenerator接口)作为key,将其存放到DefaultListableBeanFactory中的
BeanDefinitionMap,这个BeanDefinitionMap其实就是一个ConcurrentHashMap。同时,beanName也被存入到
beanDefinitionNames中,这个beanDefinitionNames是一个List类型的数据结构。
4 BeanDefinition的自定义修改
在从BeanDefinitionMap中取出BeanDefinition进行实例化之前,我们可以使用BeanFactoryPostProcessor
来修改Bean定义的属性,常修改的属性有:class(类信息)、autowireMode(自动注入模式)、
constructorArgumentValues(构造参数值)等。
5 BeanDefinition和Bean的关系
我们知道BeanDefinition是Bean在spring中的定义形态,有了BeanDefinition我们就可以创建Bean。
BeanDefinition与Bean的关系,就好比类与对象的关系。类在spring中的数据结构就是BeanDefinition,
根据BeanDefinition得到的对象就是我们需要的Bean.我们可以根据BeanDefinition里面的属性(如:类名、构造函数、
构造函数参数),使用反射进行对象bean的创建。
6 BeanDefinition的实现类
BeanDefinition是一个接口,是一个抽象的定义,实际使用的是其实现类,如ChildBeanDefinition、
RootBeanDefinition、AnnotatedBeanDefinition接口GenericBeanDefinition,还有GenericBeanDefinition的
实现类AnnotatedGenericBeanDefinition、ScannedGenericBeanDefinition等。
- RootBeanDefinition:
代表一个xml,java Config来的BeanDefinition
- ChildBeanDefinition:
可以让子BeanDefinition定义拥有从父母哪里继承配置的能力
- GenericBeanDefinition:
spring2.5后注册bean首选的是GenericBeanDefinition。GenericBeanDefinition允许动态的设置父
bean.GenericBeanDefinition可以作为RootBeanDefinition与ChildBeanDefinition的替代品。
- AnnotatedBeanDefinition接口:
表示注解类型BeanDefinition。有两个重要的属性,AnnotationMetadata,MethodMetadata分别表示BeanDefinition
的注解元信息和方法元信息实现了此接口的BeanDefinition可以获取到注解元数据和方法元数据。
- AnnotatedGenericBeanDefinition类:
表示@Configuration注解注释的BeanDefinition类
- ScannedGenericBeanDefinition类:
表示@Component、@Service、@Controller等注解注释的Bean类
User.class、UserMapper.class、UserService.class、UserController.class经过下面的过程可以得到:
UserBean.class、UserMapperBean.class、UserServiceBean.class、UserControllerBean.class