spring BeanDefinition介绍
我们知道描述一个对象我们可以创建一个类,比如user对象,那么描述一个类呢?用Class可以描述一个类,BeanDefinition就是spring用了描述Bean信息的类比如(是否懒加载、类名、类加载器等等),BeanDefinition是spring的核心,能否理解BeanDefinition关系到spring源码的阅读情况。
spring源码分析
spirng源码编译完成后,创建一个自定义的模块编写如下代码
通过AnnotationConfigApplicationContext完成一次spring的模拟,接下来就是看AnnotationConfigApplicationContext是怎么工作的,
AnnotationConfigApplicationContext继承了GenericApplicationContext,所以先看GenericApplicationContext构造方法的执行,生成了一个默认的beanFactory的工厂,我们的类获取都是通过此工厂提供的getBean方法获取的。
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
然后回到AnnotationConfigApplicationContext的构造方法,通过AnnotatedBeanDefinitionReader生成了一个解析器
/**
* Create a new AnnotationConfigApplicationContext that needs to be populated
* through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
*/
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
this.reader = new AnnotatedBeanDefinitionReader(this);
//标记结束
createAnnotatedBeanDefReader.end();
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
执行进去我们可以看到最后调用到registerAnnotationConfigProcessors为spring添加内部自带的后置处理器,
public static Set
registerAnnotationConfigProcessors( BeanDefinitionRegistry
registry, @Nullable Object source) {
1、ConfigurationClassPostProcessor (后面说明)
2、AutowiredAnnotationBeanPostProcessor
3、EventListenerMethodProcessor
4、DefaultEventListenerFactory
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
通过registry.registerBeanDefinition最终把bd放在map中如下图
原来spring的容器就是一个map,我们的对象都被放在map里面,当然spring有很多map用来解决不同的问题(如循环依赖等)
this.scanner = new ClassPathBeanDefinitionScanner(this);创建一个资源解析器
AnnotationConfigApplicationContext的构造方法就分析完成,主要功能
1、创建一个beanFactory的工厂
2、添加spring内置的后置处理器
3、创建资源解析器
/**
* Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given component classes and automatically refreshing the context.
* @param componentClasses one or more component classes — for example,
* {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
默认构造器分析完成,register(componentClasses)主要是把自己的类转换成BeanDefinition,然后注册到map里面去
最后通过registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); 完成bd的注册
/**
* Register the given bean definition with the given bean factory.
* @param definitionHolder the bean definition including name and aliases
* @param registry the bean factory to register with
* @throws BeanDefinitionStoreException if registration failed
*/
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // 注册bena
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
至此 父类构造方法,AnnotationConfigApplicationContext,register(componentClasses);方法已经分析完成,通过此方法大致能明白spring中初始化的核心点在哪。