1、什么是spring应用上下文?
接口org.springframework.context.ApplicationContext表示spring上下文,下面2个实现类
org.springframework.context.support.ClassPathXmlApplicationContext
org.springframework.context.annotation.AnnotationConfigApplicationContext
2、应用上文生命周期(14个阶段)
1、创建spring应用上下文
2、上下文启动准备阶段
3、BeanFactory创建阶段
4、BeanFactory准备阶段
5、BeanFactory后置处理阶段
6、BeanFactory注册BeanPostProcessor阶段
7、初始化内建Bean:MessageSource
8、初始化内建Bean:Spring事件广播器
9、Spring应用上下文刷新阶段
10、Spring事件监听器注册阶段
11、单例bean实例化阶段
12、BeanFactory初始化完成阶段
13、Spring应用上下文启动完成阶段
14、Spring应用上下文关闭阶段
3、Spring应用上下文的使用
看下这段代码,是不是很熟悉,这就是spring上下文最常见的用法,稍后我们以这段代码为例,结合spring源码,来细说每个阶段的细节。
@Configuration
@ComponentScan
public class MainConfig {
public static void main(String[] args) {
//1.创建spring上下文
AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext();
//2.上下文中注册bean
configApplicationContext.register(MainConfig.class);
//3.刷新spring上下文,内部会启动spring上下文
configApplicationContext.refresh();
//4.关闭spring上下文
System.out.println("stop ok!");
}
}
4、阶段1:创建Spring应用上下文
对应这段代码
AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext();
看一下其类图,这里主要列出了AnnotationConfigApplicationContext2个父类
当调用子类的构造器的时候,默认会自动先调用父类的构造器,先来看一下GenericApplicationContext构造器源码,如下,将beanFactory创建好了。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
再来看看AnnotationConfigApplicationContext构造器源码,如下:
public AnnotationConfigApplicationContext() {
//创建AnnotatedBeanDefinitionReader:用来读取及注册通过注解方式定义的bean
this.reader = new AnnotatedBeanDefinitionReader(this); //@1
//创建ClassPathBeanDefinitionScanner:bean定义扫描器,可以扫描包中的类,对满足条件的类,会将其注册到spring容器中
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
@1:new AnnotatedBeanDefinitionReader(this),进入这个方法内部,最终会走到下面这个方法,非常关键的一个方法,会向spring容器中注册5个关键的bean,这几个bean都是非常很重要的。
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) {
//1、注册ConfigurationClassPostProcessor,这是个非常关键的类,实现了BeanDefinitionRegistryPostProcessor接口
// ConfigurationClassPostProcessor这个类主要做的事情:负责所有bean的注册,如果想看bean注册源码的,可以在其postProcessBeanDefinitionRegistry方法中设置断点
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));
}
//2、注册AutowiredAnnotationBeanPostProcessor:负责处理@Autowire注解
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));
}
//3、注册CommonAnnotationBeanPostProcessor:负责处理@Resource注解
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));
}
//4、注册EventListenerMethodProcessor:负责处理@EventListener标注的方法,即事件处理器
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
//5、注册DefaultEventListenerFactory:负责将@EventListener标注的方法包装为ApplicationListener对象
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
再来捋一下上面这段代码,主要向spring容器中注册了5个关键的bean
1、ConfigurationClassPostProcessor:这是个非常关键的类,建议去看一下他的源码,基本上我们自定义的bean都是通过这个类注册的,下面这些注解都是在这个类中处理的
@Configuration
@Component
@PropertySource
@PropertySources
@ComponentScan
@ComponentScans
@Import
@ImportResource
@Bean
2、AutowiredAnnotationBeanPostProcessor:负责处理@Autowire注解
3、注册CommonAnnotationBeanPostProcessor:负责处理@Resource注解
4、注册EventListenerMethodProcessor:负责处理@EventListener标注的方法,即事件处理器
5、注册DefaultEventListenerFactory:负责将@EventListener标注的方法包装为ApplicationListener对象
5、阶段2~阶段13
阶段2到阶段13,这中间的12个阶段都位于refresh方法中,所以refresh方法非常很重要,需要多花时间研究这个方法。
refresh方法源码如下:
org.springframework.context.support.AbstractApplicationContext#refresh
@Override
public void refresh() throws BeansException, IllegalStateException {
// 阶段2:Spring应用上下文启动准备阶段
prepareRefresh();
// 阶段3:BeanFactory创建阶段
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 阶段4:BeanFactory准备阶段
prepareBeanFactory(beanFactory);
try {
// 阶段5:BeanFactory后置处理阶段
postProcessBeanFactory(beanFactory);
// 阶段6:BeanFactory注册BeanPostProcessor阶段
invokeBeanFactoryPostProcessors(beanFactory);
// 阶段7:注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);