本文利用AnnotationConfigApplicationContext 注册加载Spring上下文配置
//spring版本5.3
public class AnnotationApplicationContextTest {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig.class);
ac.getBean(UserBeanTest.class);
}
}
1.创建AnnotationConfigApplicationContext实例对象
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
//1.创建AnnotationConfigApplicationContext实例对象
this();
//2.注册参数bean到spring上下文中
register(componentClasses);
//3.刷新Spring容器
refresh();
}
这段代码就做上面1,2,3 三件事情
1.1.创建AnnotationConfigApplicationContext实例对象
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
//创建AnnotatedBeanDefinitionReader对象
this.reader = new AnnotatedBeanDefinitionReader(this);
//创建ClassPathBeanDefinitionScanner对象
createAnnotatedBeanDefReader.end();
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public class AnnotatedBeanDefinitionReader {
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 注入默认的注解处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
}
分析
创建AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner对象,跟踪代码可知,在实例化AnnotatedBeanDefinitionReader对象是,默认注入了5个实例。
在AnnotatedBeanDefinitionReader实例化时会根据具体情况注入一下类分别是:
// 用户配置Configuration注解,实现了BeanDefinitionRegistryPostProcessor接口
ConfigurationClassPostProcessor
// 用于配置Autowired注解,实现了MergedBeanDefinitionPostProcessor接口
AutowiredAnnotationBeanPostProcessor
// 用于配置Required注解,实现了MergedBeanDefinitionPostProcessor接口
RequiredAnnotationBeanPostProcessor
// 用于配置JSR-250注解,实现了InstantiationAwareBeanPostProcessor接口
CommonAnnotationBeanPostProcessor
// 用于配置JPA注解
PersistenceAnnotationBeanPostProcessor
// 用于配置EventListener注解,实现了SmartInitializingSingleton接口
EventListenerMethodProcessor
// EventListener工厂
DefaultEventListenerFactory
1.2 注册参数bean到spring上下文中
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
.tag("classes", () -> Arrays.toString(componentClasses));
this.reader.register(componentClasses);
registerComponentClass.end();
}
分析
跟踪代码可以看到,在运行完register(annotatedClasses);方法后,BeanFactory会多以个configurationTest属性,该类就是我们启动时传入的参数MainConfig.class
1.3 刷新Spring容器
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
//1.准备刷新的上下文环境
prepareRefresh();
//2.初始化BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3.对BeanFactory进行各种功能填充
prepareBeanFactory(beanFactory);
try {
//4.子类覆盖方法做额外的处理
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
//5.注册,实例化,调用各种BeanFactory处理器
invokeBeanFactoryPostProcessors(beanFactory);
//6.注册拦截Bean创建的Bean处理,这里只是注册,真正调用是再拿去Bean的时候
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
//7.为上下文初始化Message源,即不同语言的消息体,国际化处理
initMessageSource();
//8.初始化应用消息广播器,并放到applicationEventMulticaster bean中
initApplicationEventMulticaster();
//9.留给子类来初始化其他bean
onRefresh();
//10.在所有注册的bean中查找Listener bean,注册到消息广播中
registerListeners();
//11.初始化剩下的单实例(非惰性)
finishBeanFactoryInitialization(beanFactory);
//12.完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
contextRefresh.end();
}
}
}
https://blog.csdn.net/u010811939/article/details/80625917