本文主要利用AnnotationConfigApplicationContext 注册加载Spring上下文
项目启动:
@Configuration
@ComponentScan(basePackages="com.gz.spring.springbean")
public class SpringBeanConfigutionTest {
@SuppressWarnings("resource")
public static void main(String[] args) {
AnnotationConfigApplicationContext ac =
new AnnotationConfigApplicationContext(SpringBeanConfigutionTest.class);
ac.getBean(SpringBeanTest.class);
ac.getBean(SpringBeanTest.class);
}
}
代码如下:
public AnnotationConfigApplicationContext(Class>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
在这段代码中主要做了3件事
创建AnnotationConfigApplicationContext实例对象,时序图1.1。
注册参数bean到spring上下文中,时序图1.2。
刷新Spring容器,时序图1.3。
时序图如下:
代码
public AnnotationConfigApplicationContext() {
// 创建AnnotatedBeanDefinitionReader对象
this.reader = new AnnotatedBeanDefinitionReader(this);
// 创建ClassPathBeanDefinitionScanner对象
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
代码
public void register(Class>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
// 将annotatedClasses注入到spring上下中
this.reader.register(annotatedClasses);
}
分析
跟踪代码可以看到,在运行完register(annotatedClasses);方法后,BeanFactory会多以个configurationTest属性,该类就是我们启动时传入的参数SpringBeanConfigutionTest.class
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// ⑴.准备刷新的上下文环境
prepareRefresh();
// ⑵.初始化BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// ⑶.对BeanFactory进行各种功能填充
prepareBeanFactory(beanFactory);
try {
// ⑷.子类覆盖方法做额外的处理
postProcessBeanFactory(beanFactory);
// ⑸.注册,实例化,调用各种BeanFactory处理器
invokeBeanFactoryPostProcessors(beanFactory);
// ⑹.注册拦截Bean创建的Bean处理,这里只是注册,真正调用是再拿去Bean的时候
registerBeanPostProcessors(beanFactory);
// ⑺.为上下文初始化Message源,即不同语言的消息体,国际化处理
initMessageSource();
// ⑻.初始化应用消息广播器,并放到applicationEventMulticaster bean中
initApplicationEventMulticaster();
// ⑼.留给子类来初始化其他bean
onRefresh();
// ⑽.在所有注册的bean中查找Listener bean,注册到消息广播中
registerListeners();
// ⑾.初始化剩下的单实例(非惰性)
finishBeanFactoryInitialization(beanFactory);
// ⑿.完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
分析:
⑴.准备刷新的上下文环境
⑵.初始化BeanFactory
⑶.对BeanFactory进行各种功能填充
⑷.子类覆盖方法做额外的处理
⑸.注册,实例化,调用各种BeanFactory处理器
⑹.注册拦截Bean创建的Bean处理,这里只是注册,真正调用是再拿去Bean的时候
⑺.为上下文初始化Message源,即不同语言的消息体,国际化处理
⑻.初始化应用消息广播器,并放到applicationEventMulticaster bean中
⑼.留给子类来初始化其他bean
⑽.在所有注册的bean中查找Listener bean,注册到消息广播中
⑾.初始化剩下的单实例(非惰性)
⑿.完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
刷新在父类AbstractBeanFactory中实现,原理详情请看【Spring注解配置加载解析原理二】