Spring之BeanDefinition(三)
文章目录
- Spring之BeanDefinition(三)
- 一、Spring的启动类三行代码研究
- 二、Spring创建工厂类型和属性
- 三、Spring中内置的BeanDefinition
- 四、注册配置类
- 五、BeanDefinition总结
一、Spring的启动类三行代码研究
一切还是得从spring中的三行代码说起:
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(LiAppCOnfig.class);
applicationContext.refresh();
下面的研究就需要从这三行代码分别来进行说明。
二、Spring创建工厂类型和属性
首先从第一行代码开始研究
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
从第一行代码进去,看一下源码说明:
public AnnotationConfigApplicationContext() {
// 创建Spring中的容器对象: this.beanFactory = new DefaultListableBeanFactory();
// 这行代码是我自己添加的!因为默认访问的就是父类中的默认无参构造方法
super();
// ....
}
而在new DefaultListableBeanFactory()的时候,首先可以知道的是beanFactory是DefaultListableBeanFactory类型的
可以看一下其中的现有的成员属性变量:
/** Whether to allow re-registration of a different definition with the same name. */
private boolean allowBeanDefinitionOverriding = true;
/** Whether to allow eager class loading even for lazy-init beans. */
private boolean allowEagerClassLoading = true;
/** Resolver to use for checking if a bean definition is an autowire candidate. */
private AutowireCandidateResolver autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;
/** Map from dependency type to corresponding autowired value. */
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** Map from bean name to merged BeanDefinitionHolder. */
private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256);
/** Map of singleton and non-singleton bean names, keyed by dependency type. */
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
/** Map of singleton-only bean names, keyed by dependency type. */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
/** List of bean definition names, in registration order. */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
/** List of names of manually registered singletons, in registration order. */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
其中可以看到跟BeanDefinition相关的成员变量有一下几个:
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** Map from bean name to merged BeanDefinitionHolder. */
private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256);
/** Map of singleton and non-singleton bean names, keyed by dependency type. */
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
/** Map of singleton-only bean names, keyed by dependency type. */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
/** List of bean definition names, in registration order. */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
/** List of names of manually registered singletons, in registration order. */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
不言而喻,就是用来盛放BeanDefinition的,其中每种都有不同的用途!
三、Spring中内置的BeanDefinition
public AnnotationConfigApplicationContext() {
super();
// 额外会创建StandardEnvironment
this.reader = new AnnotatedBeanDefinitionReader(this);
}
从第二行代码开始说起,进入到org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)方法中来
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
// .........
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 注册ConfigurationClassPostProcessor类型的BeanDefinition
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def,CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册AutowiredAnnotationBeanPostProcessor类型的BeanDefinition
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册CommonAnnotationBeanPostProcessor类型的BeanDefinition
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册PersistenceAnnotationBeanPostProcessor类型的BeanDefinition
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// .........
return beanDefs;
}
首先Spring在这里内置了五个重要的BeanDefinition,但是其中有三个是常用且重要的BeanDefinition:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor
首先要来说明描述这三个BeanDefinition所能够起到的作用:
- ConfigurationClassPostProcessor:①用来实现扫描配置类且注册到BeanDefinitionMap中去的;②用来实现对添加了@Configuration注解的类中的@Bean方法来进行解析的。(CGLIB实现一个类中的方法可以从容器中来获取得到对象);
- AutowiredAnnotationBeanPostProcessor:①对类中的成员变量上添加了@Autowired注解的成员变量从容器中来进行获取;②对成员方法上添加了@Autowired注解的方法中的参数来从容器中来获取得到对应的值;
- CommonAnnotationBeanPostProcessor:①对类中的成员变量上添加了@Resource注解的成员变量从容器中来进行获取;②对成员方法上添加了@Resource注解的方法中的参数来从容器中来获取得到对应的值;
那么分析上面三个中的一个即可!下面以ConfigurationClassPostProcessor来进行举例说明:
// 注册AutowiredAnnotationBeanPostProcessor类型的BeanDefinition
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
①首先判断在BeanDefinitionMap中是否包含了key为org.springframework.context.annotation.internalConfigurationAnnotationProcessor名称的BeanDefinition,如果不包含,那么首先来进行创建对应类型的BeanDefinition;
②然后注册到put到beanDefinitionMap中去
第二步代码可以参考一下源代码:
// 注册AutowiredAnnotationBeanPostProcessor类型的BeanDefinition
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
// 调用方法来进行注册
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
看一下注册代码:
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 注册关键信息:参数:beanName和对应的RootBeanDefinition
registry.registerBeanDefinition(beanName, definition); // BeanDefinitinoMap
return new BeanDefinitionHolder(definition, beanName);
}
进入到org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition中来:
然后下面的方法分为以下几个步骤:
1、首先校验一下BeanDefinition是否是合法的
((AbstractBeanDefinition) beanDefinition).validate();
2、判断在beanDefinitionMap中是否已经存在?如果不存在,那么进行添加,走的是else逻辑:
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
放入到这两个集合(beanDefinitionMap和beanDefinitionNames)中来
四、注册配置类
直接来看三行代码中的第二行代码:
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 这行代码
applicationContext.register(LiAppCOnfig.class);
applicationContext.refresh();
直接进去可以看到下面的代码:
this.reader.register(componentClasses);
这里的reader=new AnnotatedBeanDefinitionReader(this);,是在第一行代码中代码中进行创建的。
那么来看一下LiAppCOnfig这个类
@Configuration
@ComponentScan(basePackages = "com.guang")
public class LiAppCOnfig {}
这里有两个点:
①指定需要扫描的包。这个是一定要需要的,需要配置扫描包路径下面的类;
②声明当前类为配置类。这里的声明一定要存在的;
这里的this.reader = new AnnotatedBeanDefinitionReader(this);
那么看一下其中的register方法
private <T> void doRegisterBean(Class<T> beanClass, String name,
Class<? extends Annotation>[] qualifiers,Supplier<T> supplier,
BeanDefinitionCustomizer[] customizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
// 解析@Scope注解的结果为ScopeMetadata
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
// ............
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册配置类
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
①首先将对应的class来进行封装,封装成一个全新的AnnotatedGenericBeanDefinition,所以说启动类是有特殊含义的BeanDefinition;
②然后对当前配置类对应的BeanDefinition来进行封装解析;
③注册到beanDefinitionMap中去;
五、BeanDefinition总结
参考ProcessOn地址:https://www.processon.com/view/link/64c5f7d3b9f7806c73d7af0e