深入源码分析SpringIOC(三)

IOC的扩展点之灵活运用Spring框架


一个好的框架不仅需要做到 满足面向对象的原则,有足够 健壮性,还需要有 强大的易扩展性,而Spring就做到了这些。本文将介绍Spring中的一些扩展点,以及其调用时序,更好理解以至于灵活地去使用。

1. 初始化ApplicationContext

回忆一下ApplicationContext初始化过程中refresh这个方法:

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        //调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        //告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从
        //子类的refreshBeanFactory()方法启动
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        //为BeanFactory配置容器特性,例如类加载器、事件处理器等
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            //为容器的某些子类指定特殊的BeanPost事件处理器
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            //调用所有注册的BeanFactoryPostProcessor的Bean
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            //为BeanFactory注册BeanPost事件处理器.
            //BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            //初始化信息源,和国际化相关.
            initMessageSource();

            // Initialize event multicaster for this context.
            //初始化容器事件传播器.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            //调用子类的某些特殊Bean初始化方法
            onRefresh();

            // Check for listener beans and register them.
            //为事件传播器注册事件监听器.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            //初始化所有剩余的单例Bean
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            //初始化容器的生命周期事件处理器,并发布容器的生命周期事件
            finishRefresh();
        }

        //异常处理,略...

    }
}

由第一篇文章中介绍的,初始化开头调用了ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 方法,此时将所有的Bean转换成Bean信息封装类BeanDefinition对象注册进beanFactory,第二篇文章中介绍,初始化末尾调用了finishBeanFactoryInitialization(beanFactory); 方法进行所有单例Bean的初始化,那么,refresh中中间还有那么多的方法,是干什么用的呢?(这里只提与自定义扩展有关的需要关注的方法):

  1. invokeBeanFactoryPostProcessors(beanFactory) :调用所有实现了BeanFactoryPostProcessor接口的Bean的一个回调方法
  2. registerBeanPostProcessors(beanFactory)注册所有实现了BeanPostProcessor接口的Bean,注意这里仅仅是注册,在Bean的初始化时会遍历所有注册好的Processor调用回调方法
  3. initApplicationEventMulticaster():初始化监听事件的容器,此处可自定义,如无定义使用默认监听器容器。顾名思义,监听器容器就是用来存放监听器,并且可以回调监听器的方法。
  4. registerListeners():注册所有的监听器,也就是将所有实现ApplicationListener的Bean注册进上面第三步的监听器容器。
  5. finishRefresh() :在IOC容器初始化结束之后,会调用实现了Lifecycle的Bean的start()方法。并且发布一个事件publishEvent(new ContextRefreshedEvent(this)) 给监听器容器,监听器容器会通知所有监听器,并回调执行监听器方法(传入event)。

根据上面5个步骤,我们大致可以将扩展点分为3点:

  • BeanFactory级别的回调方法
  • Bean级别的回调方法
  • 监听器事件驱动式回调

参考《Spring源码深度解析》:BeanFactoryPostProcessor可以对Bean的定义(配置元数据)进行处理。也就是说SpringIOC容器允许BeanFactoryPostProcessor在容器实际实例化任何其他Bean之前读取配置元数据,并有可能修改它。如果你愿意,你可以配置多个BeanFactoryPostProcessor。

如果你想改变实际的Bean实例,那么你最好使用BeanPostProcessor。同样地,BeanFactoryPostProcessor的作用域范围是容器级的。

2. BeanFactory的后处理

2.1 BeanFactoryPostProcessor典型应用

参考《Spring源码深度解析》:BeanFactoryPostProcessor典型应用PropertyPlaceholderConfigurer

<bean id="message" class="distConfig.HelloMessage">
	<property name="mes">
    	<value>${bean.message}</value>
    </property>
</bean>

<bean id="mesHandler" class="org.Springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="location">
    	<list>
        	<value>config/bean.properties</value>
        </list>
    </property>
</bean>

在bean.properties文件中配置如下:

bean.message=Hi,can you find me?

其中,PropertyPlaceholderConfigurer这个类实现了BeanFactoryPostProcessor接口,所以在refresh的时序上来看,它会在载入、注册所有Bean的配置信息之后,去执行BeanFactoryPostProcessor接口的postProcessBeanFactory方法,此类的这个方法就是将占位符进行解析,注意此类location属性正是包含了配置文件,从而达到从配置文件中替换bean中的占位符的效果。

2.2 BeanFactoryPostProcessor注册与调用过程

回到refresh的时序中,假设现在已经加载注册完所有Bean的配置信息了,接着调用invokeBeanFactoryPostProcessors(beanFactory) 方法:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    //调用实现BeanFactoryPostProcessor接口的Bean的postProcessBeanFactory方法
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
    // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

委派PostProcessorRegistrationDelegate类去执行相应回调方法:

public static void invokeBeanFactoryPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<>();
	
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
		//首先处理已经注册了的BeanFactoryPostProcessor(硬编码)
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            //先处理BeanDefinitionRegistryPostProcessor,其是BeanFactoryPostProcessor子类
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
                //这里执行BeanDefinitionRegistryPostProcessor的回调方法
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                //剩余不是BeanDefinitionRegistryPostProcessor的加入此List
                regularPostProcessors.add(postProcessor);
            }
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        // Separate between BeanDefinitionRegistryPostProcessors that implement
        // PriorityOrdered, Ordered, and the rest.
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
        //这里从beanFactory从寻找BeanDefinitionRegistryPostProcessor类型的Bean
        //先执行的是实现了PriorityOrdered接口的那些回调
        String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        //进行排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        //执行BeanDefinitionRegistryPostProcessor的回调方法
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        //寻找beanFactory中BeanDefinitionRegistryPostProcessor
        //第二执行的是实现了Ordered接口的那些回调
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        //排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        //执行BeanDefinitionRegistryPostProcessor的回调方法
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
        //寻找beanFactory中BeanDefinitionRegistryPostProcessor
        //第三执行的是其他普通的回调
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            //排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            //执行BeanDefinitionRegistryPostProcessor的回调方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
        }

        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        //执行所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        //执行所有其他的BeanFactoryPostProcessor的postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
        // Invoke factory processors registered with the context instance.
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    //寻找beanFactory中所有实现了BeanFactoryPostProcessor接口的Bean
    String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    //存放实现了PriorityOrdered接口的回调,会优先执行
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    //存放实现了Ordered接口的回调,会次之执行
    List<String> orderedPostProcessorNames = new ArrayList<>();
    //存放没有实现上面两个接口的回调,最后执行
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        if (processedBeans.contains(ppName)) {
            // skip - already processed in first phase above
            //跳过 - 在前面的阶段已经执行过了
        }
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            //筛选出实现了PriorityOrdered的回调
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            //筛选出实现了Ordered的回调
            orderedPostProcessorNames.add(ppName);
        }
        else {
            //其它没有实现上述两个接口的回调
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    //优先执行postProcessBeanFactory方法
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    //次之执行postProcessBeanFactory方法
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // Finally, invoke all other BeanFactoryPostProcessors.
    //最后执行postProcessBeanFactory方法
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // Clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    beanFactory.clearMetadataCache();
}

这个方法有点长,这里我总结一下其中干了什么:

  1. 首先执行 postProcessBeanDefinitionRegistry 方法:
    • 执行所有硬编码下的BeanDefinitionRegistryPostProcessor
    • 执行容器中的BeanDefinitionRegistryPostProcessor类型的Bean(有Order排序)
  2. 然后执行postProcessBeanFactory 方法:
    • 执行上述所有的BeanDefinitionRegistryPostProcessor
    • 执行硬编码下不是BeanDefinitionRegistryPostProcessor 的那些BeanFactoryPostProcessor
    • 执行容器中剩余的BeanFactoryPostProcessor 类型的Bean (有Order排序)

2.3 BeanFactory后处理小结

从以上可以知道,我们可以在刚加载完Bean的配置后,拿到registry或是beanFactory,可以对配置中的元数据进行更改,就像开头例子中所描述的,将bean中一个属性占位符替换掉,这个过程是使用了回调方法,但它们都只是容器级别的,父容器不会进行后处理。

  1. 我们可以使用上述两种Processor,在Bean初始化之前对Bean的配置信息进行修改,注意是初始化之前,也就代表Bean都没有实例化的时候,这样一来你修改的Bean的配置信息就可以在初始化Bean阶段将Bean初始化成你希望看到的
  2. 其中有两个优先级接口,你需要实现此接口,就能获得优先处理的权限,从源码可以看到详细过程:
    • PriorityOrdered:最优先,复写getOrder方法设置当前优先级。
    • Ordered :优先级次之,在PriorityOrdered之后执行,复写getOrder方法设置当前优先级。
    • 没有实现上述接口最后执行,注意,优先级接口是最优先比较的,然后才会比较getOrder设置的优先级。

3. BeanPostProcessor

此回调与上述回调不同的地方在于,上述关注的时序是在加载完Bean配置信息之后,也就是注重修改Bean配置元信息,BeanPostProcessor回调注重于在Bean初始化完成之后进行的回调,其中AOP则是需要等到Bean初始化完成之后才进行动态代理,不然实例化或是依赖注入都没有完成,就进行动态代理的话, 不符合逻辑不说,还阻止了Bean的初始化过程。

3.1 注册BeanPostProcessor

让我们的时序回到refresh初始化容器中去,此时我们加载完Bean的配置之后,又执行完BeanFactory后处理了,现在将会执行registerBeanPostProcessors(beanFactory); 方法进行BeanPostProcessor的注册:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

依然是委托另一个类取做的注册:

public static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    //从beanFactory中取出所有BeanPostProcessor类型的beanName
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    //BeanPostProcessor也具有与上面一样的优先级的处理
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    //遍历所有找到了的Bean
    for (String ppName : postProcessorNames) {
        //判断是否为最优先级接口
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            //如果是,则初始化并取出该Bean
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            //放入最优先List中
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        //判断是否为次之优先接口
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            //将名称加入到List中
            orderedPostProcessorNames.add(ppName);
        }
        else {
            //剩下的就是最后执行,加入List
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // First, register the BeanPostProcessors that implement PriorityOrdered.
    //先将这些实现最优先接口的类进行排序
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    //注册这些BeanPostProcessor到beanFactory中
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
    //由于上面只是将名称加入,并没有getBean,所以这里先遍历名称
    for (String ppName : orderedPostProcessorNames) {
        //一一getBean初始化并取出Bean
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        //加入次之优先的List
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    //排序
    sortPostProcessors(orderedPostProcessors, beanFactory);
    //注册
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
    //同上
    for (String ppName : nonOrderedPostProcessorNames) {
        //同上
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        //没有优先级,最后执行
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    //不需要进行排序,直接注册
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // Finally, re-register all internal BeanPostProcessors.
    sortPostProcessors(internalPostProcessors, beanFactory);
    //这里不会重复注册相同的BeanPostProcessor,因为在注册过程会进行去重操作
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

注册过程:

private static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
	//遍历List进行注册
    for (BeanPostProcessor postProcessor : postProcessors) {
        beanFactory.addBeanPostProcessor(postProcessor);
    }
}
/** BeanPostProcessors to apply in createBean */
//存放所有的BeanPostProcessor
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    //先进行去重操作,确保不会重复
    this.beanPostProcessors.remove(beanPostProcessor);
    //注册,其实就是将此Bean放入一个List中
    this.beanPostProcessors.add(beanPostProcessor);
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
        this.hasInstantiationAwareBeanPostProcessors = true;
    }
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
        this.hasDestructionAwareBeanPostProcessors = true;
    }
}

看完了注册过程,接下来就是调用过程了,这些回调Bean在什么时候会进行回调呢?

3.2 执行BeanPostProcessor

先来看看BeanPostProcessor接口描述了什么:

public interface BeanPostProcessor {

	//为在Bean的初始化前提供回调入口
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
    
	//为在Bean的初始化之后提供回调入口
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
}

那么调用时机具体是在哪里呢?进入doCreateBean方法,实例化且依赖注入完成:

//这里是依赖注入
populateBean(beanName, mbd, instanceWrapper);
//initializeBean为执行回调的方法,注意此时已经初始化且依赖注入完了
exposedObject = initializeBean(beanName, exposedObject, mbd);
//初始容器创建的Bean实例对象,为其添加BeanPostProcessor后置处理器
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    //JDK的安全机制验证权限
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        //为Bean实例对象包装相关属性,如名称,类加载器,所属容器等信息
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    //对BeanPostProcessor后置处理器的postProcessBeforeInitialization
    //回调方法的调用,为Bean实例初始化前做一些处理
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    //调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置
    //文件中通过init-method属性指定的
    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
    }
    //对BeanPostProcessor后置处理器的postProcessAfterInitialization
    //回调方法的调用,为Bean实例初始化之后做一些处理
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

我们来一一分析这些扩展点:

3.2.1 部分Aware接口的回调

首先是invokeAwareMethods方法:

private void invokeAwareMethods(final String beanName, final Object bean) {
    //Bean如果继承了Aware,将会执行Bean的一些Aware方法
    if (bean instanceof Aware) {
        //如果是实现BeanNameAware的话
        if (bean instanceof BeanNameAware) {
            //将此Bean的BeanName放入此方法参数并执行
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        //如果是实现BeanClassLoaderAware的话
        if (bean instanceof BeanClassLoaderAware的话) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                //将ClassLoader放入此方法参数并执行
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        //如果是实现BeanFactoryAware的话
        if (bean instanceof BeanFactoryAware) {
            //放入beanFactory实例
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

这里只是部分三个Aware,后面还有一些Aware接口,以供有需要的Bean注入你需要的资源,例如,你只需要实现BeanFactoryAware这个接口,实现setBeanFactory方法,即可拿到beanFactory实例,Aware接口方便的提供了你所需要的资源

3.2.2 Bean的前处理

前处理由applyBeanPostProcessorsBeforeInitialization方法执行:

@Override
//调用BeanPostProcessor后置处理器实例对象初始化之前的处理方法
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
    throws BeansException {
    Object result = existingBean;
    //遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        //调用Bean实例所有的后置处理中的初始化前处理方法,为Bean实例对象在
        //初始化之前做一些自定义的处理操作
        Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

这里getBeanPostProcessors()方法会将我们前面所说的注册的那些BeanPostProcessor全部遍历执行,因为已经优先级排序add了,所以此时List都是有序执行的。

3.2.3 Bean的自定义初始化

invokeInitMethods开始Bean的初始化处理,注意此时不是指实例化与依赖注入,这两个过程已经执行过:

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
    throws Throwable {
	
    //判断Bean是否实现了InitializingBean接口,实现了才会进行自定义初始化
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isDebugEnabled()) {
            logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {					
                    //执行自定义初始化方法
                    ((InitializingBean) bean).afterPropertiesSet();
                    return null;
                }, getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            //执行自定义初始化方法
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        //寻找配置Bean时配置的init方法
        String initMethodName = mbd.getInitMethodName();
        //这里会先忽略掉afterPropertiesSet这个方法,因为已经执行过了
        if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
            //这里会获取Method对象,执行你配置的init方法
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

由上面的代码可以知道,在自定义初始化中,你有两种方法可以进行自定义初始化:

  1. 实现InitializingBean接口

    public interface InitializingBean {
    
    	void afterPropertiesSet() throws Exception;
    }
    

    afterPropertiesSet方法中实现你所自定义的逻辑。

  2. 在配置Bean时配置一个init方法

3.2.4 Bean的后处理

applyBeanPostProcessorsAfterInitialization方法完成:

@Override
//调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    //遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        //调用Bean实例所有的后置处理中的初始化后处理方法,为Bean实例对象在
        //初始化之后做一些自定义的处理操作
        Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

与后处理一样,遍历所有已经注册过的BeanPostProcessor进行轮流调用postProcessAfterInitialization方法。

3.3其他的Aware接口

在refresh方法中,加载Bean配置之后,执行BeanFactory后处理之前,其实还注册了一些BeanPostProcessor,是在refresh的prepareBeanFactory方法中注册的:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   
    //略...

    // Configure the bean factory with context callbacks.
    //这里会添加一个回调Aware的Processor
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
    //忽略以下Aware接口,不进行依赖注入
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    //注册以下类型,在依赖注入时如果遇到例如BeanFactory类型的依赖,直接注入beanFactory的值
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    //略...
}

这里略过一些暂时不讨论的方法,可以知道,这里会固定注册一个名为ApplicationContextAwareProcessor的Processor,来看看它的前后处理方法都做了什么吧:

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
    return bean;
}

在后处理中没有做任何逻辑,继续看看前处理:

@Override
@Nullable
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    AccessControlContext acc = null;

    if (System.getSecurityManager() != null &&
        (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
         bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
         bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
        acc = this.applicationContext.getBeanFactory().getAccessControlContext();
    }

    if (acc != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            //执行Aware接口的方法
            invokeAwareInterfaces(bean);
            return null;
        }, acc);
    }
    else {
        //执行Aware接口的方法
        invokeAwareInterfaces(bean);
    }

    return bean;
}

这里大部分都在判断一些其他的东西,我们重点只看invokeAwareInterfaces

private void invokeAwareInterfaces(Object bean) {
    //判断Bean是Aware才往下执行
    if (bean instanceof Aware) {
        //如果实现了EnvironmentAware
        if (bean instanceof EnvironmentAware) {
            //将applicationContext的enviroment变量放入
            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
        }
        if (bean instanceof EmbeddedValueResolverAware) {
            ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
        }
        //如果实现了ResourceLoaderAware
        if (bean instanceof ResourceLoaderAware) {
            //将资源加载器放入
            ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
        }
        if (bean instanceof ApplicationEventPublisherAware) {
            ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
        }
        if (bean instanceof MessageSourceAware) {
            ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
        }
        //如果实现了ApplicationContextAware
        if (bean instanceof ApplicationContextAware) {
            //将上下文对象放入
            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
        }
    }
}

这里我就不一一注释说明了,也就是说,容器在Bean初始化完成之后,会判断此Bean是否是Aware,除了上述我们说的那三个Aware,这里还有很多个Aware供用户实现,可以拿到更多各种各样的资源。

3.4 其他的BeanPostProcessor

这里还有一种BeanPostProcessor的调用时序,即为BeanPostProcessor的子类InstantiationAwareBeanPostProcessor

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

    //在Bean实例化之前的回调入口
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

    //Bean实例化之前,上面的回调入口之后的入口
	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}
    
    //在Bean实例化之后,依赖注入时对注入属性进行更改的回调入口
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		return pvs;
	}
}

这个接口提供了更加多的回调时机的入口,并且额外提供了在依赖注入时的回调时机入口。我们需要关注的点就在,这些入口究竟在什么地方执行?

首先看看前处理的时机。回到实际创建Bean实例的方法中:

//创建Bean实例对象
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {

    //略..
    
    RootBeanDefinition mbdToUse = mbd;

    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    //判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
    
    //略..

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        //执行上述的回调入口
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    
    //略..
    
    try {
        //创建Bean的入口
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }
    //略..
}

其中resolveBeforeInstantiation方法执行了两个回调,从这里我们可以知道,时机就在实例化Bean之前,此时Bean甚至连实例化都还没做

@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    //刚开始beforeInstantiationResolved为null,所以第一次是会进入该if语句块的
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        //这里会保证该Bean是已经被处理过的才会进入这里(除了第一次)
        //不知读者是否记得,在注册BeanPostProcessor的时候,
        //会判断该BeanPostProcessor是否是InstantiationAwareBeanPostProcessor
        //如果是的话,hasInstantiationAwareBeanPostProcessors会为true,进入以下语句块
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                //回调入口,进行回调前处理
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    //如果bean不为空,代表已经自定义实例化了,所以这里不是执行InstantiationAwareBeanPostProcessor的回调后处理
                    //而是执行普通BeanPostProcessor的回调后处理,后面读者可以注意一下
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        //bean不为null,证明被处理过了,下一次将还会进入这个语句块
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        //只执行那些InstantiationAwareBeanPostProcessor
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            //前处理回调入口
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}
@Override
//调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    //遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        //调用Bean实例所有的后置处理中的初始化后处理方法,为Bean实例对象在
        //初始化之后做一些自定义的处理操作
        Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

注意,InstantiationAwareBeanPostProcessor与上述的BeanPostProcessor使用场景不一样,InstantiationAwareBeanPostProcessor的前处理更多是希望将你想要的Bean根据你自己的方式进行自定义实例化,所以你可以看到,在creatBean的主逻辑中,只要该前处理返回的Bean不为null,即代表此Bean已经自定义初始化完成,会接着去执行普通BeanPostProcessor的后处理,当这里返回的Bean不为null,在createBean方法中,将不会进行后面的操作(例实例化、依赖注入、回调初始化之类之类的操作),直接返回InstantiationAwareBeanPostProcessor前处理之后返回的bean。

其次看看后处理和依赖注入回调的时机,我们来到依赖注入的方法populateBean

//将Bean属性设置到生成的实例对象上
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   
	//略..
    
    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    boolean continueWithPropertyPopulation = true;

    //上面说过,在注册时会判断,存在即hasInstantiationAwareBeanPostProcessors为true
    //所以此时可以根据注册时的判断来判断是否存在InstantiationAwareBeanPostProcessor
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            //只执行InstantiationAwareBeanPostProcessor
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                //执行后处理
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }

    //如果后处理中有返回false的,这里将不进行依赖注入直接返回了
    if (!continueWithPropertyPopulation) {
        return;
    }
    
    //略..

    //对非autowiring的属性进行依赖注入处理

    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

    if (hasInstAwareBpps || needsDepCheck) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        if (hasInstAwareBpps) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                //只处理InstantiationAwareBeanPostProcessor
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    //这里执行依赖注入的回调
                    pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    //这里返回值为null,将不进行依赖注入,直接返回
                    if (pvs == null) {
                        return;
                    }
                }
            }
        }
        if (needsDepCheck) {
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    }

    if (pvs != null) {
        //对属性进行注入
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

到这里我们可以知道,InstantiationAwareBeanPostProcessor的后处理是为了判断是否依赖注入的,如果返回false,将不进行依赖注入的功能,而依赖注入的回调方法,是为了对注入的属性进行某种自定义操作的,如果不返回null,将会根据自定义处理了的PropertyValues属性值进行依赖注入。

3.5 小结

  1. 实现Aware接口: 实现对应方法,方法中可以拿到你想要的资源
  2. 实现InitializingBean接口: 在接口方法中实现你所想要初始化的逻辑,此时序是在Bean实例化且依赖注入完,Bean进行前处理之后,后处理之前会调用的。
  3. 实现BeanPostProcessor接口: 在接口两个入口中实现你所想要操作Bean的逻辑,前处理的时序是在Bean实例化且依赖注入完成之后,后处理的时序是在前处理完成且初始化方法完成之后。
  4. 实现InstantiationAwareBeanPostProcessor接口:
    • 实现前处理方法: 你 可以自定义Bean的初始化过程,将不会执行之后Spring的创建Bean方法doCreateBean,直接返回你所自定义的Bean实例。
    • 实现后处理方法: 你可以自定义当前Bean是否进行依赖注入,返回false就不会进行依赖注入了。
    • 实现依赖注入回调方法: 你可以操作注入的属性值,使用自定义操作后的属性值进行依赖注入,同时返回null将不会进行依赖注入。

4. 事件驱动编程(监听器)

4.1 初始化监听器的管理器

回忆一下refresh方法,其中有一个过程是初始化监听器容器initApplicationEventMulticaster

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    //判断beanFactory中是否存在名为applicationEventMulticaster的Bean
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        //如果有,初始化该Bean并取出
        this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else {
        //如果到了这里,说明没有自定义applicationEventMulticaster
        //Spring默认会创建一个SimpleApplicationEventMulticaster
        //放入IOC容器,将其当作是监听器容器
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        //注册此实例到IOC容器中
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                         APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                         "': using default [" + this.applicationEventMulticaster + "]");
        }
    }
}

如果用户没有自定义监听器容器,将配置一个默认的监听器容器

4.2 注册监听器

回到refresh方法,接下来会注册各个监听器registerListeners

protected void registerListeners() {
    // Register statically specified listeners first.
    //首先注册硬编码的监听器
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    //获取所有IOC容器中ApplicationListener类型的BeanName
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    //遍历BeanName,依次注册
    for (String listenerBeanName : listenerBeanNames) {
        //这里会使用我们上面初始化好的监听器容器去注册监听器
        //不要担心重复,监听器是用Set集合存放,自带去重功能
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // Publish early application events now that we finally have a multicaster...
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

注册监听器必须是要有监听器容器,所以上面会先初始化一个监听器容器,如果用户没有设置,那么Spring将默认创建一个出来。

4.3 发布事件通知

注册监听器的过程,我们可以知道,监听器统一存放在名为applicationEventMulticaster的Bean中,统一管理。此Bean默认实现是SimpleApplicationEventMulticaster

//通知监听器的方法
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    //获取所有的监听器,遍历它们
    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        Executor executor = getTaskExecutor();
        if (executor != null) {
            //通知监听器
            executor.execute(() -> invokeListener(listener, event));
        }
        else {
            //通知监听器
            invokeListener(listener, event);
        }
    }
}

protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
    ErrorHandler errorHandler = getErrorHandler();
    if (errorHandler != null) {
        try {
            //真正通知监听器的方法
            doInvokeListener(listener, event);
        }
        catch (Throwable err) {
            errorHandler.handleError(err);
        }
    }
    else {
        //真正通知监听器的方法
        doInvokeListener(listener, event);
    }
}

@SuppressWarnings({"unchecked", "rawtypes"})
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    try {
        //调用监听器的onApplicationEvent方法,传入一个事件源
        listener.onApplicationEvent(event);
    }
    //catch过程,略...
}

我们可以知道,监听器容器统一管理监听器,并对外提供通知监听器的方法,可以看出onApplicationEvent方法即为监听器的回调方法:

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

	/**
	 * Handle an application event.
	 * @param event the event to respond to
	 */
	void onApplicationEvent(E event);
}

是一个功能接口,面向函数式编程,其中方法定义为传入一个源(这里的源必须是ApplicationEvent的)。返回空值。

4.4 ApplicationContext发布事件发布通知

那么在Spring中是什么时候会通知监听器的呢?在AbstractApplicationContext中有这样一个方法:

@Override
public void publishEvent(ApplicationEvent event) {
    //传入事件源
    publishEvent(event, null);
}

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
    Assert.notNull(event, "Event must not be null");
    if (logger.isTraceEnabled()) {
        logger.trace("Publishing event in " + getDisplayName() + ": " + event);
    }

    // Decorate event as an ApplicationEvent if necessary
    ApplicationEvent applicationEvent;
    //对事件源类型进行处理
    if (event instanceof ApplicationEvent) {
        applicationEvent = (ApplicationEvent) event;
    }
    else {
        applicationEvent = new PayloadApplicationEvent<>(this, event);
        if (eventType == null) {
            eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
        }
    }

    // Multicast right now if possible - or lazily once the multicaster is initialized
    if (this.earlyApplicationEvents != null) {
        this.earlyApplicationEvents.add(applicationEvent);
    }
    else {
        //执行通知的方法,同时所有监听器
        getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    }

    // Publish event via parent context as well...
    //如果有父容器,也通知父容器的监听器
    if (this.parent != null) {
        if (this.parent instanceof AbstractApplicationContext) {
            //父容器也发布事件进行通知
            ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
        }
        else {
            //父容器也发布事件进行通知
            this.parent.publishEvent(event);
        }
    }
}

也就是说,我们如果可以拿到ApplicationContext对象,通过调用该对象的publishEvent方法,即可发布事件并且通知所有监听器。

在开头我们也有提到,在IOC容器初始化完成的末尾,会执行一个方法finishRefresh,此方法内部会发布事件进行通知,告诉监听器此时IOC容器初始化完成:

protected void finishRefresh() {
    // Clear context-level resource caches (such as ASM metadata from scanning).
    clearResourceCaches();

    // Initialize lifecycle processor for this context.
    initLifecycleProcessor();

    // Propagate refresh to lifecycle processor first.
    getLifecycleProcessor().onRefresh();

    // Publish the final event.
    //发布事件源,封装当前对象,发布通知
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    LiveBeansView.registerApplicationContext(this);
}

此时正是执行了我们上面分析的发布事件源发布通知的方法publishEvent

4.5 小结

  1. 自定义监听器容器: 需将此BeanName设置为applicationEventMulticaster 的Bean,或者不自定义也是可以的,Spring会提供一个默认的监听器容器
  2. 配置监听器: 让Bean实现ApplicationListener接口,这样这个Bean就是一个监听器,Spring会注册它。然后在方法中可以定义对应事件驱动的方法。
  3. 发布事件通知: 可以通过Aware接口,或是@Autowired依赖注入一个ApplicationContext,拿到上下文对象之后,执行publishEvent方法即可发布通知给监听器。

5. Lifecycle

参考《Spring源码深度解析》一书:在Spring中还提供了Lifecycle接口,Lifecycle中包含start/stop方法,实现此接口后Spring会保证在启动的时候调用其start方法开始生命周期,并在Spring关闭的时候调用stop方法来结束生命周期,通常用来配置后台程序,在启动后一直允许(如对MQ进行轮询等)。而ApplicationContext的初始化最后正式保证了这一功能的实现。

这里提到ApplicationContext的初始化最后,正是我们上面提到的finishRefresh方法:

protected void finishRefresh() {
    // Clear context-level resource caches (such as ASM metadata from scanning).
    clearResourceCaches();

    // Initialize lifecycle processor for this context.
    //先初始化LifecycleProcessor
    //此类类似上述监听器容器,用来管理所有Lifecycle的Bean
    //负责调用Lifecycle的Bean的start/stop方法
    initLifecycleProcessor();

    // Propagate refresh to lifecycle processor first.
    //委派上述初始化的LifecycleProcessor去调用start方法
    getLifecycleProcessor().onRefresh();

    // Publish the final event.
    //发布事件源,封装当前对象,发布通知
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    LiveBeansView.registerApplicationContext(this);
}

5.1 初始化Lifecycle的管理器

Lifecycle类似上面说到的监听器容器(管理器),用于管理实现了Lifecycle接口的Bean, initLifecycleProcessor():

protected void initLifecycleProcessor() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    //判断beanFactory中是否有名为lifecycleProcessor的Bean
    if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
        //如果有,将其初始化并取出,作为Lifecycle的管理器
        this.lifecycleProcessor =
            beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
        }
    }
    else {
        //如果用户没有自定义lifecycleProcessor,Spring将默认创建一个
        DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
        defaultProcessor.setBeanFactory(beanFactory);
        //作为Lifecycle的管理器
        this.lifecycleProcessor = defaultProcessor;
        //将此Lifecycle的管理器注册到IOC容器中作为一个Bean
        beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate LifecycleProcessor with name '" +
                         LIFECYCLE_PROCESSOR_BEAN_NAME +
                         "': using default [" + this.lifecycleProcessor + "]");
        }
    }
}

类似的,Lifecycle的管理器也可以自定义,若用户没有自定义,则创建一个默认的。

5.2 Lifecycle开始生命周期

由于此时IOC容器已经初始化完成,所以将会开启所有Lifecyclestart方法,方式就是委派管理器去执行getLifecycleProcessor().onRefresh():

@Override
public void onRefresh() {
    startBeans(true);
    this.running = true;
}

private void startBeans(boolean autoStartupOnly) {
    //拿到所有容器中实现Lifecycle接口的Bean
    Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
    Map<Integer, LifecycleGroup> phases = new HashMap<>();
    lifecycleBeans.forEach((beanName, bean) -> {
        if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
            int phase = getPhase(bean);
            LifecycleGroup group = phases.get(phase);
            if (group == null) {
                group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                phases.put(phase, group);
            }
            group.add(beanName, bean);
        }
    });
    if (!phases.isEmpty()) {
        List<Integer> keys = new ArrayList<>(phases.keySet());
        Collections.sort(keys);
        for (Integer key : keys) {
            //执行Lifecycle的start方法
            phases.get(key).start();
        }
    }
}

至于stop方法,我没有去找具体在哪里执行,不过我猜想应该是在容器关闭时就会执行stop方法。

6. 总结

以上,我们说了很多很多关于Spring的扩展点,这里再进行总结一下。

  • 如果你希望修改Bean的配置信息, 并且在Bean初始化的时候可以被使用到: 可以实现BeanFactoryPostProcessor接口,在相应回调方法中实现相应的逻辑。具体应用:配置Bean时占位符的替换,亦或是某些Bean的属性转换(电话号码中间几位的屏蔽),总而言之如果希望修改Bean配置信息,按照你希望的配置来进行初始化,就实现此接口。

  • 如果你希望在Bean初始化完成之后对Bean有什么操作: 可以实现BeanPostProcessor接口。具体应用:AOP,AOP的原理其实是动态代理,实现AOP的核心类就实现了BeanPostProcessor接口,并且保证在Bean初始化(实例化与依赖注入)之后进行后处理,判断Bean是否应该被AOP,如果需要,则动态代理此Bean,返回代理后的proxy对象,IOC容器将使用proxy对象作为此Bean,完成AOP的操作。

  • 如果你希望某个Bean按照你的方式进行初始化: 而不是IOC那些实例化、依赖注入、各种回调方法,那么你可以实现InstantiationAwareBeanPostProcessor,实现前处理方法来自定义Bean的初始化过程,返回实例即为此Bean,如果返回null的话IOC容器将继续初始化该Bean,所以可以判断某个Bean是自定义的初始化,剩下的Bean依然可以正常初始化。

  • 如果你希望修改某个Bean的依赖注入属性,亦或是控制某个Bean不要进行依赖注入: 你可以实现InstantiationAwareBeanPostProcessor这个接口的依赖注入回调方法或是后处理方法。前者可以返回一个你修改后的属性封装对象,在接下来的处理中会针对你修改后的属性封装对象进行依赖注入,如果返回null将不会进行依赖注入。而后者只控制是否进行依赖注入,两者的区别与时序希望读者区分清楚,它们的共同点在都可以控制是否进行依赖注入,但侧重点不同

  • 如果你希望获取容器的某个资源:例如ClassLoader、BeanFactory、ApplicationContext、ResourceLoader等等一系列资源,你可以实现相对应的Aware接口,并且将类交给IOC容器管理,此类作为Bean将在你实现的Aware接口的对应方法中注入你所想要的属性。亦或是使用依赖注入的方式,也可以得到你想要的资源,原理在上面的3.3节其他的Aware接口中有提到,注册了对应的依赖:

    @Autowired
    private ApplicationContext applicationContext
    
  • 如果你希望在Bean初始化完,执行一个类似初始化的方法:你可以实现InitializingBean接口,在对应方法中实现你想初始化的逻辑,时机是在Bean实例化、依赖注入、BeanPostProcessor的前处理之后,后处理之前将会执行的。

  • 如果你希望注册监听器:实现ApplicationListener接口,并将类交给IOC容器管理,就可以自动注册监听器了,然后在对应方法中写具体通知方法之后需要做的事件逻辑。注册完监听器,就少不了发布事件,你可以在任意地方获取到上下文对象(方式有两种,上面都有提到),然后调用上下文对象的publishEvent方法即可发布事件,你所配置的监听器都会收到消息并执行你自定义的逻辑。

  • 如果你希望伴随IOC容器有一个生命周期的动作:你可以让类实现Lifecycle接口,实现对应start/stop方法,其将会在容器初始化完成后执行start,在start开始此Bean的生命周期的逻辑,达到一个生命周期的效果。

讲到这里,IOC容器的介绍也就告一段落了,我希望读者看到这里,能意识到IOC容器并不是解耦那么简单,因为有了IOC容器,才有AOP,才有各种各样灵活的处理,如果没有IOC容器去管理那些对象,我们需要做的事情可多太多太多了,IOC容器管理对象极大简化了我们的开发过程

猜你喜欢

转载自blog.csdn.net/qq_41737716/article/details/84990660