分析register(componentClasses)方法
1、重点查看doRegisterBean()方法
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
/**
* AnnotatedGenericBeanDefinition可以理解为一种数据结构,是用来描述Bean的,这里的作用就是把传入的标记了注解
* 的类 ,转为AnnotatedGenericBeanDefinition数据结构,里面有一个getMetadata方法,可以拿到类上的注解
*
* -----------------------------------------------------------------------------------
* 通过AnnotatedGenericBeanDefinition的构造器获取配置类的beanDefinition,这里是不是
* 似曾相似,在注册ConfigurationClassPostProcessor类的时候,也是通过构造方法去获得BeanDefinition的,
* 只不过当时是通过RootBeanDefinition去获得,现在是通过AnnotatedGenericBeanDefinition去获得
* ------------------------------------------------------------------------------------
*/
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
/** 判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析 */
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
/** 解析bean的作用域,如果没有设置的话,默认为单例 */
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// 获取beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
/** 解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description */
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
/**
* 把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中(这个不是很重要,可以简单的理解为方便传参)
*/
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
/**
* 注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册,
* DefaultListableBeanFactory维护着一系列信息,比如beanDefinitionNames,beanDefinitionMap
* beanDefinitionNames是一个List<String>,用来保存beanName
* beanDefinitionMap是一个Map,用来保存beanName和beanDefinition
*/
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
2、进入registerBeanDefinition()方法,这个方法主要做了一件事,就是将definitionHolder封装对象里面的配置类的beanDefinition和beanName存放到beanDefinitionMap和beanDefinitionNames集合中
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
/** 获取beanName */
String beanName = definitionHolder.getBeanName();
/** 注册我们配置类的beanDefinition和beanName到集合中 */
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
配置类的beanDefinition注册到beanDefinitionMap集合
配置类的beanName注册到beanNames集合
以常规方式去注册配置类,此方法中除了第一个参数,其他参数都是默认值。
1、通过AnnotatedGenericBeanDefinition的构造方法,获得配置类的BeanDefinition;
2、判断需不需要跳过注册,Spring中有一个@Condition注解,如果不满足条件,就会跳过这个类的
注册;
3、然后是解析作用域,如果没有设置的话,默认为单例;
4、获得BeanName;
5、 解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,
DependsOn,Role,Description;
6、把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中;
7、注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册;
以上注册配置类分析完毕。
refresh()方法
以上的分析只是实例化了一个工厂,在this()方法中注册了一些原生的内置的Bean(特别重要的ConfigurationClassPostProcessor);在register()方法中主要是注册了我们传入的配置类;真正的大头是在第三行代码:
refresh();
过于负责,这里简单说一下,就是解析配置类,找到配置类上的@ComponentScan注解找到需要扫描的包,扫描所有标注了@Controller、@Service、@Respository等注解,将符合条件的bean解析成beanDefinition并注册到集合中。
Spring Bean的生命周期
- 实例化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为
连Autowired注解都是没有解析的; - 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了;
- 如果Bean实现了BeanNameAware接口,则调用setBeanName方法;
- 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;
- 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;
- 调用BeanPostProcessor的postProcessBeforeInitialization方法;
- 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法;
- 如果Bean定义了init-method方法,则调用Bean的init-method方法;
- 调用BeanPostProcessor的postProcessAfterInitialization方法;当进行到这一步,Bean已经被准备就绪了,一直停留在应用的上下文中,直到被销毁;
- 如果应用的上下文被销毁了,如果Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method声明了销毁方法也会被调用。