Spring创建Bean,会经过一系列生命周期的流程,而Spring启动,其实就是为了后续创建Bean做一些准备工作,本篇以及下一篇文章都是来详细分析Spring的启动过程。
目录
一、Spring启动的大致流程
二、Spring加载流程之AnnotatedBeanDefinitionReader
1.Spring程序入口
2.AnnotationConfigApplicationContext的构造函数
3.AnnotatedBeanDefinitionReader的构造函数
4.AnnotationConfigUtils中的registerAnnotationConfigProcessors()
三、refresh()底层原理流程
1.如何理解refresh()?
2.refresh()执行流程拆解分析
3.refresh()执行流程源码注释
四、BeanFactoryPostProcessor
五、BeanDefinitionRegistryPostProcessor
六、Lifecycle的使用
通常,我们说的Spring启动,其实就是构造ApplicationContext对象以及调用refresh()方法的过程。那么这个过程会涉及到哪些操作呢?以下基于AnnotationConfigApplicationContext来进行说明:
1. 构造一个BeanFactory对象;
2. 构造BeanDefinitionReader,向BeanFactory注册各个注解模式需要的后置处理器;
3. 解析配置类,得到BeanDefinition,并注册到BeanFactory中;
① 解析@ComponentScan,此时就会完成扫描
② 解析@Import
③ 解析@Bean
④ ...
4.由于Spring启动过程中要创建非懒加载的单例Bean对象,那么就需要用到BeanPostProcessor,所以Spring在启动过程中就需要做两件事:
4.1. 生成默认的BeanPostProcessor对象,并添加到BeanFactory中:
① AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value 注解;
② CommonAnnotationBeanPostProcessor:处理@Resource、@PostConstruct、 @PreDestroy 注解;
③ ApplicationContextAwareProcessor:处理ApplicationContextAware等回调
4.2. 找到外部用户自定义的BeanPostProcessor对象(类型为BeanPostProcessor的Bean对象),并添加到BeanFactory中;
5. ApplicationContext支持国际化,需要初始化MessageSource对象;
6. ApplicationContext支持事件机制,还需要初始化ApplicationEventMulticaster对象;
7. 把用户定义的ApplicationListener对象添加到ApplicationContext中,等Spring启动完了就要发布事件了;
8. 创建非懒加载的单例Bean对象,并存在BeanFactory的单例池中;
9. 调用LifecycleBean的start()方法;
10. 发布ContextRefreshedEvent事件;
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
AnnotationConfigApplicationContext是Spring的高级容器,有多个构造方法,以下是基于AnnotationConfigApplicationContext(Class>... componentClasses)来分析,在这个构造方法中,首先会执行自己的无参构造方法---this(),在this()中会先执行父类GenericApplicationContext的默认构造方法;
public AnnotationConfigApplicationContext(Class>... componentClasses) {
/**构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
*这里由于它有父类,所以会先调用父类的构造方法,初始化DefaultListableBeanFactory
*AnnotationConfigApplicationContext容器无参构造器--->父类GenericApplicationContext无参构造器,创建this.beanFactory = new DefaultListableBeanFactory();
*/
this();
//注册相关信息
register(componentClasses);
//刷新容器---核心
refresh();
}
public GenericApplicationContext() {
// 初始化一个beanFactory
this.beanFactory = new DefaultListableBeanFactory();
}
这个DefaultListableBeanFactory,非常重要,Spring加载的bean都会放到这个Bean工厂中,
当然GenericApplicationContext的父类AbstractApplicationContext,包括AbstractApplicationContext的父类DefaultResourceLoader都有默认构造方法的;
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
public DefaultResourceLoader() {
}
这些提前初始化的属性到后面都会用到,以下是继承关系图:
回到AnnotationConfigApplicationContext(Class>... componentClasses)构造方法中的this(),
构造AnnotatedBeanDefinitionReader,主要作用是对BeanFactory进行设置和添加一些基础的PostProcessor(后置处理器),同时可以通过reader进行BeanDefinition的注册;
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
/** 什么是bean定义 ? BeanDefinition
* 创建一个读取注解的Bean定义读取器,它的register()方法能够将类解析成为一个BeanDefination,然后将BeanDefination对象存到beanDefinationMap中,而beanDefinationMap是在Bean工厂中
* 完成了Spring内部BeanDefinition的注册(主要是后置处理器)
* 额外会创建StandardEnvironment
*/
this.reader = new AnnotatedBeanDefinitionReader(this);//this 指的就是DefaultListableBeanFactory
createAnnotatedBeanDefReader.end();
/** 创建BeanDefinition扫描器,可以用来扫描包或者类继而转换为BeanDefinition
* Spring默认的扫描器其实不是这个scanner对象,而是在后面自己又重新new了一个ClassPathBeanDefinitionScanner
* Spring在执行工程后置处理器ConfigurationClassPostProcessor时,去扫描包时会new一个ClassPathBeanDefinitionScanner
* 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
对于AnnotatedBeanDefinitionReader()构造函数里面的参数registry其实就是DefaultListableBeanFactory;
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;
// 解析器,用来解析@Conditional注解的
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
/** registerAnnotationConfigProcessors,向BeanFactory注册各个注解模式需要的后置处理器
* 根据名字顾名思义就是->注册注解配置的处理器,也就是这个方法里面会注册一些用于处理注解的处理器
*/
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
public static Set registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 获取beanFactory也就是DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
/**
* 设置比较器,它是一个Comparator,可以用来进行排序,比如new ArrayList<>().sort(Comparator),主要能解析@Order和@Priority
* 会获取某个对象上的Order注解或者通过实现Ordered接口所定义的值进行排序,在日常开发中可以利用这个类来进行排序
*/
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
/**
* 设置依赖注入的候选处理器,用来判断某个Bean能不能用来进行依赖注入
* 可以看到只要不是ContextAnnotationAutowireCandidateResolver类型 直接升级为最强类型
*/
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set beanDefs = new LinkedHashSet<>(8);
/**注册ConfigurationClassPostProcessor类型的BeanDefinition,ConfigurationClassPostProcessor是一个工厂后置处理器
* 这个后置处理器非常重要,基本上类上面的注解都在这里面判断并解析,Spring的包扫描也在里面完成
*/
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));
}
/**
* 注册AutowiredAnnotationBeanPostProcessor类型的BeanDefinition
* 处理@Autowired注解的,它是一个bean的后置处理器,在bean的属性注入的时候会用到
*/
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));
}
/**
* 注册CommonAnnotationBeanPostProcessor类型的BeanDefinition
* 处理一些公共注解的,它是一个bean的后置处理器,可以处理@PostConstruct和@PreDestroy还有@Resource等
*/
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
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));
}
// 注册PersistenceAnnotationBeanPostProcessor类型的BeanDefinition
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/**
* 注册EventListenerMethodProcessor类型的BeanDefinition,用来处理@EventListener注解的
* Spring实现事件监听的方式有很多种,其中一种就是在方法上添加@EventListener注解
*/
if (
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));
}
// 注册DefaultEventListenerFactory类型的BeanDefinition,用来处理@EventListener注解的
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;
}
/**
* Load or refresh the persistent representation of the configuration, which
* might be from Java-based configuration, an XML file, a properties file, a
* relational database schema, or some other format.
* As this is a startup method, it should destroy already created singletons
* if it fails, to avoid dangling resources. In other words, after invocation
* of this method, either all or no singletons at all should be instantiated.
* @throws BeansException if the bean factory could not be initialized
* @throws IllegalStateException if already initialized and multiple refresh
* attempts are not supported
*/
void refresh() throws BeansException, IllegalStateException;
这是ConfigurableApplicationContext接口上refresh()方法的注释,意思是:加载或刷新持久化的配置,可能是XML文件、属性文件或关系数据库中存储的;由于这是一个启动方法,如果失败,它应 该销毁已经创建的单例,以避免占用资源,换句话说,在调用该方法之后,应该实例化所有的单例, 或者根本不实例化单例 。 有个地方需要注意:ApplicationContext关闭之后不代表JVM也关闭了,ApplicationContext是属于JVM的,ApplicationContext也是JVM中的一个对象。
在Spring的设计中,也提供可以刷新的ApplicationContext和不可以刷新的ApplicationContext, 比如:
AbstractRefreshableApplicationContext extends AbstractApplicationContext
就是可以刷新的;
GenericApplicationContext extends AbstractApplicationContext
就是不可以刷新的。 AnnotationConfigApplicationContext继承的是GenericApplicationContext,所以它是不能刷新的; AnnotationConfigWebApplicationContext继承的是 AbstractRefreshableWebApplicationContext,所以它是可以刷新的,上面说的不能刷新是指不能重复刷新,只能调用一次refresh方法,第二次时会报错。
2.1. prepareRefresh():
① 可以允许子容器设置一些内容到Environment中;
② 验证Environment中是否包括了必须要有的属性;
2.2. obtainFreshBeanFactory():进行BeanFactory的refresh,在这里会去调用子类的 refreshBeanFactory方法,具体子类是怎么刷新的得看子类的实现,最后再调用子类的 getBeanFactory方法,重新得到一个BeanFactory;
2.3. prepareBeanFactory(beanFactory):
① 设置beanFactory的类加载器,由于创建bean是由Bean工厂来创建,所有如果设置了类加载器,会把类加载器设置到Bean工厂中;
② 设置SpringEL表达式解析器:StandardBeanExpressionResolver,用来解析Spring中的表达式,例如: @Value("#{}");
③ 添加PropertyEditorRegistrar:ResourceEditorRegistrar,属性编辑器注册器,用来注册一些默认的PropertyEditor ;
④ 添加一个Bean的后置处理器:ApplicationContextAwareProcessor,是一个BeanPostProcessor,用来执行EnvironmentAware、ApplicationContextAware、ApplicationEventPublisherAware 等回调方法
⑤ 添加ignoredDependencyInterface:可以向这个属性中添加一些接口,如果某个类实现了其中的一个或多个接口,并且这个类中的某些set方法在接口中也存在,那么这个set方法在自动注入的 时候是不会执行的,比如EnvironmentAware这个接口,如果某个类实现了这个接口,那就必须实现它的setEnvironment方法,而这是一个set方法,和Spring中的autowire是冲突 的,那么Spring在自动注入时是不会调用setEnvironment方法的,而是等到回调Aware接口时再来调用(注意,这个功能仅限于xml的autowire,@Autowired注解是忽略这个属性的,这些接口有 EnvironmentAware
EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware
MessageSourceAware、ApplicationContextAware
其实在容器启动构造BeanFactory(DefaultListableBeanFactory)的时候,ignoredDependencyInterface就已经提前添加了另外三个,分別是BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
2.4. 添加resolvableDependencies:在byType进行依赖注入时,会先从这个属性中根据类型找bean
① BeanFactory.class:当前BeanFactory对象
② ResourceLoader.class:当前ApplicationContext对象
③ ApplicationEventPublisher.class:当前ApplicationContext对象
④ ApplicationContext.class:当前ApplicationContext对象
2.5. 添加一个Bean的后置处理器:ApplicationListenerDetector,是一个 BeanPostProcessor,用来判断某个Bean是不是ApplicationListener,如果是则把这个 Bean添加到ApplicationContext中去,注意一个ApplicationListener只能是单例的;
2.6. 添加一个Bean的后置处理器:LoadTimeWeaverAwareProcessor,是一个 BeanPostProcessor,用来判断某个Bean是不是实现了LoadTimeWeaverAware接口,如果实现了则把ApplicationContext中的loadTimeWeaver回调setLoadTimeWeaver方法设置给该Bean;
2.7. 添加一些单例bean到单例池:
① "environment":Environment对象
② "systemProperties":System.getSystemProperties()返回的Map对象
③ "systemEnvironment":System.getSystemEnvironment)返回的Map对象
④ "applicationStartup":DefaultApplicationStartup对象
2.8. postProcessBeanFactory(beanFactory) : 提供给AbstractApplicationContext的子类进行扩 展,具体的子类,可以继续向BeanFactory中再添加一些东西;
2.9. invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor,到这一步,在BeanFactory中已经存在一个BeanFactoryPostProcessor: ConfigurationClassPostProcessor,它也是一个BeanDefinitionRegistryPostProcessor
2.9.1. 执行通过ApplicationContext添加进来的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;
2.9.2. 执行BeanFactory中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;
2.9.3. 执行BeanFactory中实现了Ordered接口的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;
2.9.4. 执行BeanFactory中其他的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;
2.9.5. 执行上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法 ;
2.9.6. 执行通过ApplicationContext添加进来的BeanFactoryPostProcessor的 postProcessBeanFactory()方法 ;
2.9.7. 执行BeanFactory中实现了PriorityOrdered接口的BeanFactoryPostProcessor的 postProcessBeanFactory()方法 ;
2.9.8. 执行BeanFactory中实现了Ordered接口的BeanFactoryPostProcessor的 postProcessBeanFactory()方法 ;
2.9.9. 执行BeanFactory中其他的BeanFactoryPostProcessor的postProcessBeanFactory()方法;
2.10. registerBeanPostProcessors(beanFactory):因为上面的步骤完成了扫描,这个过程中我们可能自己定义了一些BeanPostProcessor,在这一步就会把BeanFactory中所有的 BeanPostProcessor找出来实例化得到相应的对象,并添加到BeanFactory中去(属性 beanPostProcessors),最后再重新添加一个ApplicationListenerDetector对象(之前其实就添加了过,这里是为了把ApplicationListenerDetector移动到最后);
2.11. initMessageSource():ApplicationContext是支持国际化的,但不是自己完全去实现,而是利用MessageSource去实现的,而MessageSource通常是需要我们自己去定义的,如果BeanFactory中存在一个叫做"messageSource"的 BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的 messageSource属性,让ApplicationContext拥有国际化的功能;
2.12.initApplicationEventMulticaster():初始化事件监听多路广播器,如果BeanFactory中存在一个叫做"applicationEventMulticaster"的BeanDefinition,就会把这个Bean对象创建出来并赋值给ApplicationContext的applicationEventMulticaster属性,如果没有,则默认采用SimpleApplicationEventMulticaster,让ApplicationContext拥有事件发布的功能;
2.13. onRefresh():提供给AbstractApplicationContext的子类进行扩展;
2.14. registerListeners():从BeanFactory中获取ApplicationListener类型的beanName,然后添加 到ApplicationContext中的事件广播器applicationEventMulticaster中去,到这一步因为 FactoryBean还没有调用getObject()方法生成Bean对象,所以这里要在根据类型找一下 ApplicationListener,记录一下对应的beanName;
2.15. finishBeanFactoryInitialization(beanFactory):完成BeanFactory的初始化,主要就是实例化 非懒加载的单例Bean;
2.16. finishRefresh():BeanFactory的初始化完后,就到了Spring启动的最后一步了,
① 初始化ApplicationContext的lifecycleProcessor,默认情况下设置的是 DefaultLifecycleProcessor ;
② 调用lifecycleProcessor的onRefresh()方法,如果是DefaultLifecycleProcessor,那么会获取所 有类型为Lifecycle的Bean对象,然后调用它的start()方法,这就是ApplicationContext的生命 周期扩展机制;
@Override
public void onRefresh() {
startBeans(true);
}
private void startBeans(boolean autoStartupOnly) {
Map lifecycleBeans = getLifecycleBeans();
Map phases = new TreeMap<>();
// 按每个Bean的phase进行分组
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
int phase = getPhase(bean);
phases.computeIfAbsent(
phase,
p -> new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly)
).add(beanName, bean);
}
});
// 按分组执行start()
if (!phases.isEmpty()) {
phases.values().forEach(LifecycleGroup::start);
}
}
protected Map getLifecycleBeans() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
Map beans = new LinkedHashMap<>();
//获取beanFactory中所有Lifecycle类型的beanName
String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
for (String beanName : beanNames) {
String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
// 如果所定义的Lifecycle的Bean是单例并且(不是FactoryBean或是Lifecycle类型或是SmartLifecycle类型的)
if ((beanFactory.containsSingleton(beanNameToRegister) &&
(!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
Object bean = beanFactory.getBean(beanNameToCheck);
if (bean != this && bean instanceof Lifecycle) {
beans.put(beanNameToRegister, (Lifecycle) bean);
}
}
}
return beans;
}
③ 发布ContextRefreshedEvent事件;
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 启动前的准备工作
prepareRefresh();
/*
* 由于web项目中并不会先引入DefaultListableBeanFactory,在这里通知子类刷新BeanFactory,例如:AbstractRefreshableApplicationContext
* 而我们是使用new AnnotationConfigApplicationContext()的方式,就是直接返回之前引入的DefaultListableBeanFactory
* Tell the subclass to refresh the internal bean factory.
* 这里会判断能否刷新,并且返回一个BeanFactory
* 对于能进行重复刷新的子容器,刷新不代表完全清空,主要是先执行Bean的销毁,然后重新生成一个BeanFactory,再在接下来的步骤中重新去扫描等等
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 准备BeanFactory
// 1. 设置BeanFactory的类加载器、SpringEL表达式解析器、类型转化注册器
// 2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象
// 3. 记录ignoreDependencyInterface
// 4. 记录ResolvableDependency
// 5. 添加三个单例Bean
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 留的扩展方法,子类来设置一下BeanFactory
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
// BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理
// 默认情况下:
// 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition
// 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
// 这里会用ConfigurationClassPostProcessor这个类进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
// 再具体一点就是执行ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry()方法进行扫描
// 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
invokeBeanFactoryPostProcessors(beanFactory); // scanner.scan()
// Register bean processors that intercept bean creation.
// 将扫描到的BeanPostProcessors实例化并排序,并添加到BeanFactory的beanPostProcessors属性中去
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
// 设置ApplicationContext的MessageSource,可以是用户设置的,或者是DelegatingMessageSource
// ApplicationContext是支持国际化的,但不是自己完全去实现,而是利用MessageSource去实现的,而MessageSource通常是需要我们自己去定义的
initMessageSource();
// Initialize event multicaster for this context.
// 初始化事件监听多路广播器,设置ApplicationContext的applicationEventMulticaster,可以是用户设置的,或者是默认的SimpleApplicationEventMulticaster
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 给子类的模板方法
onRefresh();
// Check for listener beans and register them.
// 把定义的ApplicationListener的Bean对象,设置到ApplicationContext中去,并执行在此之前所发布的事件
registerListeners();
/**
* Instantiate all remaining (non-lazy-init) singletons.
* 创建非懒加载的单例bean,创建bean的时候需要用到BeanPostProcessor,而BeanPostProcessor都是存在于beanPostProcessors中
* 而registerBeanPostProcessors(beanFactory)就是向BeanFactory的beanPostProcessors中添加BeanPostProcessor的对象
*/
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
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();
contextRefresh.end();
}
}
}
BeanPostProcessor表示Bean的后置处理器,是用来对Bean进行加工的,类似的, BeanFactoryPostProcessor理解为BeanFactory的后置处理器,用来用对BeanFactory进行加工的, Spring支持用户自定义BeanFactoryPostProcessor的实现类,来对BeanFactory进行加工,比例如:
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
beanDefinition.setAutowireCandidate(false);
}
}
以上代码,就利用了BeanFactoryPostProcessor来拿到BeanFactory,然后获取BeanFactory内的某个BeanDefinition对象并进行修改,这一步是发生在Spring启动时,创建单例Bean之前的,所以此时对BeanDefinition就行修改是会生效的。 注意:在ApplicationContext内部有一个核心的DefaultListableBeanFactory,它实现了 ConfigurableListableBeanFactory和BeanDefinitionRegistry接口,所以ApplicationContext和 DefaultListableBeanFactory是可以注册BeanDefinition的,而ConfigurableListableBeanFactory是不能注册BeanDefinition的,只能获取BeanDefinition,对BeanDefinition做修改。
Spring还提供了一个BeanFactoryPostProcessor的子接口: BeanDefinitionRegistryPostProcessor
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws
BeansException;
}
我们可以看到BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,并新 增了一个方法,注意方法的参数为BeanDefinitionRegistry,如果我们自定义一个类来实现 BeanDefinitionRegistryPostProcessor,那么在postProcessBeanDefinitionRegistry()方法中就可 以注册BeanDefinition了。比如:
@Component
public class MyBeanDefinitionRegistryPostProcessor implements
BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws
BeansException {
AbstractBeanDefinition beanDefinition =
BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);
registry.registerBeanDefinition("user", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
beanDefinition.setAutowireCandidate(false);
}
}
Lifecycle表示的是ApplicationContext的生命周期,可以定义一个SmartLifecycle来监听 ApplicationContext的启动和关闭:
/**
* Bean有生命周期,对于Spring容器而言也有一个生命周期,如果我们想去监听Spring容器什么时候创建好?有以下做法:
* 1.监听Spring容器发布的这个事件 :publishEvent(new ContextRefreshedEvent(this))
* 2.监听当前Spring容器是否启动完了,如下做法:
*/
@Component
//@Scope("prototype")
public class MyLifecycle implements SmartLifecycle {
private boolean isRunning;
/**
* Spring容器启动完了会调用start()
*/
@Override
public void start() {
System.out.println("start...");
isRunning=true;
}
/**
* 调start()之前会执行isRunning(),判断当前是不是在运行,如果当前不是处于运行的过程中,才会调start()
* 如果是在运行(true)才能调stop方法
* 要触发stop(),要调用context.close(),或者注册关闭钩子(context.registerShutdownHook())
*/
@Override
public void stop() {
System.out.println("stop...");
}
@Override
public boolean isRunning() {
return isRunning;
}
//分组
@Override
public int getPhase() {
return 1;
}
}