千家信息网

Java图解Spring启动时的后置处理器工作流程是什么

发表于:2024-10-25 作者:千家信息网编辑
千家信息网最后更新 2024年10月25日,这篇文章主要介绍"Java图解Spring启动时的后置处理器工作流程是什么",在日常操作中,相信很多人在Java图解Spring启动时的后置处理器工作流程是什么问题上存在疑惑,小编查阅了各式资料,整理
千家信息网最后更新 2024年10月25日Java图解Spring启动时的后置处理器工作流程是什么

这篇文章主要介绍"Java图解Spring启动时的后置处理器工作流程是什么",在日常操作中,相信很多人在Java图解Spring启动时的后置处理器工作流程是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Java图解Spring启动时的后置处理器工作流程是什么"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

探究Spring的后置处理器

入口代码refresh()

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();// ......applicationContext.refresh();
public void refresh() throws BeansException, IllegalStateException {                synchronized (this.startupShutdownMonitor) {                        // Prepare this context for refreshing.                        // 启动前的准备工作:记录启动时间,活动标记为启动以及环境属性变量集合的初始化                        prepareRefresh();                        // Tell the subclass to refresh the internal bean factory.                        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();                        // Prepare the bean factory for use in this context.                        //还是一些准备工作,添加了两个后置处理器:ApplicationContextAwareProcessor,ApplicationListenerDetector                        //还设置了 忽略自动装配 和 允许自动装配 的接口                        //对环境,系统环境,系统属性三个Bean如果不存在某个bean的时候,spring就自动生成singleton bean(Not bd)                        //还设置了bean表达式解析器 等                        prepareBeanFactory(beanFactory);                        try {                                // Allows post-processing of the bean factory in context subclasses.                                // 空方法                                postProcessBeanFactory(beanFactory);                                // Invoke factory processors registered as beans in the context.                                //执行自定义的BeanFactoryProcessor和内置的BeanFactoryProcessor                                invokeBeanFactoryPostProcessors(beanFactory);                                // Register bean processors that intercept bean creation.                                registerBeanPostProcessors(beanFactory);                                // Initialize message source for this context.                                initMessageSource();                                // Initialize event multicaster for this context.                                initApplicationEventMulticaster();                                // Initialize other special beans in specific context subclasses.                                onRefresh();                                // Check for listener beans and register them.                                registerListeners();                                // Instantiate all remaining (non-lazy-init) singletons.                                finishBeanFactoryInitialization(beanFactory);                                // Last step: publish corresponding event.                                finishRefresh();                        }                        finally {                                // Reset common introspection caches in Spring's core, since we                                // might not ever need metadata for singleton beans anymore...                                resetCommonCaches();                        }                }        }

流程图

prepareRefresh剖析

该方法主要做启动前的准备工作:记录启动时间,活动标记为启动以及环境属性变量集合的初始化;

  protected void prepareRefresh() {                // Switch to active.                this.startupDate = System.currentTimeMillis();                this.closed.set(false);                this.active.set(true);                // Initialize any placeholder property sources in the context environment.                // 空方法                initPropertySources();                // Validate that all properties marked as required are resolvable:                // see ConfigurablePropertyResolver#setRequiredProperties                getEnvironment().validateRequiredProperties();                // Store pre-refresh ApplicationListeners...                if (this.earlyApplicationListeners == null) {                        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);                }                else {                        // Reset local application listeners to pre-refresh state.                        this.applicationListeners.clear();                        this.applicationListeners.addAll(this.earlyApplicationListeners);                }                // Allow for the collection of early ApplicationEvents,                // to be published once the multicaster is available...                this.earlyApplicationEvents = new LinkedHashSet<>();        }

obtainFreshBeanFactory刨析

主要是获取context上下文中的bean工厂;

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {                // CAS保证同步                refreshBeanFactory();                // 返回beanFactory- DefaultListableBeanFactory.class                ConfigurableListableBeanFactory beanFactory = getBeanFactory();                return beanFactory;        }

prepareBeanFactory刨析

做一些准备工作,添加了两个后置处理器ApplicationContextAwareProcessorApplicationListenerDetector;

设置了bean表达式解析器等;

通过工厂的接口可以设置了忽略自动装配,和允许自动装配;

对环境、系统环境、系统属性三个Bean如果不存在某个bean的时候,spring就自动生成singletonBean(Not bd);

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)  {            // Tell the internal bean factory to use the context's class loader etc.                beanFactory.setBeanClassLoader(getClassLoader());                //设置bean表达式解析器                beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));                //属性编辑器支持                beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));                // Configure the bean factory with context callbacks.                //添加一个后置处理器:ApplicationContextAwareProcessor,此后置处理处理器实现了BeanPostProcessor接口                beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));                //以下接口,忽略自动装配                beanFactory.ignoreDependencyInterface(EnvironmentAware.class);                 // .....            // BeanFactory interface not registered as resolvable type in a plain factory.                // MessageSource registered (and found for autowiring) as a bean.                //以下接口,允许自动装配,第一个参数是自动装配的类型,,第二个字段是自动装配的值                // 这个接口仅会将注入的参数XXX.class注入为指定的值,但不影响XXX.class创建Bean对象;                beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);                beanFactory.registerResolvableDependency(ResourceLoader.class, this);            // Register default environment beans.                // 环境,系统环境,系统属性 因此通常情况下,这三个Bean是没有bd的                //如果没有注册过bean名称为XXX,spring就自己创建一个名称为XXX的singleton bean                if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {                        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());                }                if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {                        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());                }                if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {                        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());                }}

invokeBeanFactoryPostProcessors剖析

执行自定义的BeanFactoryProcessor和内置的BeanFactoryProcessor;

getBeanFactoryPostProcessors()方法是我们手动通过执行addBeanFactoryPostProcessor(XX)设置自定义的后置处理器。如果初始化执行到这,没有手动增加后置处理器的话,那么此时List的size()为empty;

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {        // getBeanFactoryPostProcessors是spring允许我们手动添加BeanFactoryPostProcessor        // 即:annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX);    // 未手动添加的话,getBeanFactoryPostProcessors()为empty                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去调用invokeBeanFactoryPostProcessors()方法,从而去扫描并执行BeanFactoryProcessorBeanDefinitionRegistryPostProcessor;

我们通过继承关系看,BeanDefinitionRegistryPostProcessor实际上是继承BeanFactoryProcessor接口的;

  • BeanDefinitionRegistryPostProcessor:主要扫描类解析类;

  • BeanFactoryProcessor:主要给配置类进行增强代理;

这里面需要看我们的BeanFactory的类型;初始时BeanFactory的类型是DefaultListableBeanFactory;因此,该bean工厂是实现BeanDefinitionRegistry;

该方法的具体流程如下(按初始化进入到这里描述):

  • 循环遍历手动添加的后置处理器(并不排序);

  • 若该bfp是bdrp则直接执行bdrp. postProcessBeanDefinitionRegistry();

  • 取出内置的bdrp,分为实现了PriorityOrdered,Ordered和都没有实现的三类;

初始这里只有一个,就是我们在初始化reader()时,注册了一个ConfigurationClassPostProcessor.class;

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,                PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {}

将上面三类直接执行bdrp. postProcessBeanDefinitionRegistry();

然后将手动加入和内置的bdrp执行bfp.postProcessBeanFactory();

上面的已经执行完了:

  1. 手动添加的后置处理器的bdrf. postProcessBeanDefinitionRegistry()bfp.postProcessBeanFactory();

  2. 内置的bdrp. postProcessBeanDefinitionRegistry()

取出内置的bfp,分为实现了PriorityOrdered, Ordered和都没有实现的三类;

目前这里内置的有两个。但其中config上面已经执行过了,此处只执行下方的一个;

将上面三类直接执行bfp. postProcessBeanDefinitionRegistry();

清除缓存中的bd,因为后处理器可能有修改了原始元数据,例如替换值中的占位符;

public static void invokeBeanFactoryPostProcessors(                        ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {                // Invoke BeanDefinitionRegistryPostProcessors first, if any.                Set processedBeans = new HashSet<>();                // 如果不是BeanDefinitionRegistry 则直接执行beanFactoryPostProcessors                // 刚启动时传入的beanFactory是DefaultListableBeanFactory,他是实现了BeanDefinitionRegistry 因此会走这里                if (beanFactory instanceof BeanDefinitionRegistry) {                        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;                        // bf后置处理器集合(手动添加与bdr后置处理器集合【下面的那个集合】):因为bdrp属于bfp                        List regularPostProcessors = new ArrayList<>();                        // bdr后置处理器集合(手动添加与spring自己的)                        List registryProcessors = new ArrayList<>();                        // 循环传进来的beanFactoryPostProcessors,刚启动时未手动增加的情况下beanFactoryPostProcessors肯定没有数据                        // 因为beanFactoryPostProcessors是获得手动添加的,而不是spring扫描的                        // 只有手动调用annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX)才会有数据                        // 执行手动添加的beanFactoryPostProcessors, 如果是BeanDefinitionRegistryPostProcessor,则执行其postProcessBeanDefinitionRegistry再加到list中                        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {                                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {                                        BeanDefinitionRegistryPostProcessor registryProcessor =                                                        (BeanDefinitionRegistryPostProcessor) postProcessor;                                        registryProcessor.postProcessBeanDefinitionRegistry(registry);                                        registryProcessors.add(registryProcessor);                                }                                else {                                        regularPostProcessors.add(postProcessor);                                }                        }                        //一个临时变量,用来装载BeanDefinitionRegistryPostProcessor为了排序                        //BeanDefinitionRegistry继承了PostProcessorBeanFactoryPostProcessor                        List currentRegistryProcessors = new ArrayList<>();                        // 获得实现BeanDefinitionRegistryPostProcessor接口的类                        // 就是ConfigurationClassPostProcessor(Spring自己添加的-在reader()时增加的)                        String[] postProcessorNames =                                        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);                        for (String ppName : postProcessorNames) {                                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {                                        //获得ConfigurationClassPostProcessor类,并且放到currentRegistryProcessors                                        //ConfigurationClassPostProcessor是很重要的一个类,它实现了BeanDefinitionRegistryPostProcessor接口                                        //BeanDefinitionRegistryPostProcessor接口又实现了BeanFactoryPostProcessor接口                                        //ConfigurationClassPostProcessor是极其重要的类                                        //里面执行了扫描Bean,Import,ImportResouce等各种操作                                        //用来处理配置类(有两种情况 一种是传统意义上的配置类,一种是普通的bean)的各种逻辑                                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));                                        //把name放到processedBeans,后续会根据这个集合来判断处理器是否已经被执行过了                                        processedBeans.add(ppName);                                }                        }                        //处理排序                        sortPostProcessors(currentRegistryProcessors, beanFactory);                        //合并Processors,为什么要合并,因为registryProcessors是装载BeanDefinitionRegistryPostProcessor的                        //一开始的时候,spring只会执行BeanDefinitionRegistryPostProcessor独有的方法                        //而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor的方法                        //所以这里需要把处理器放入一个集合中,后续统一执行父类的方法                        registryProcessors.addAll(currentRegistryProcessors);                        //可以理解为执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法                        //Spring热插播的体现,像ConfigurationClassPostProcessor就相当于一个组件,Spring很多事情就是交给组件去管理                        //将spring提供的RegistryProcessors(就是这个ConfigurationClassPostProcessor)执行其postProcessBeanDefinitionRegistry                        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);                        //清空临时变量                        currentRegistryProcessors.clear();                        // 再次根据BeanDefinitionRegistryPostProcessor获得BeanName,看这个BeanName是否已经被执行过了,有没有实现Ordered接口                        // 如果没有被执行过,也实现了Ordered接口的话,把对象推送到currentRegistryProcessors,名称推送到processedBeans                        // 如果没有实现Ordered接口的话,这里不把数据加到currentRegistryProcessors,processedBeans中,后续再做处理                        // 这里才可以获得我们定义的实现了BeanDefinitionRegistryPostProcessor的Bean                        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);                        //合并Processors                        registryProcessors.addAll(currentRegistryProcessors);                        //执行有Ordered的BeanDefinitionRegistryPostProcessor                        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);                        //清空临时变量                        currentRegistryProcessors.clear();                        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.                        // 下面的代码就是执行没有实现PriorityOrdered接口也没有Ordered的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);                                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);                                currentRegistryProcessors.clear();                        }                        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.                        //registryProcessors集合装载BeanDefinitionRegistryPostProcessor                        //上面的代码是执行bfr后置处理器子类独有的方法,这里需要再把bfr后置处理器父类的方法也执行一次                        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);                        //regularPostProcessors装载BeanFactoryPostProcessor,执行BeanFactoryPostProcessor的方法                        //但是regularPostProcessors一般情况下,是不会有数据的,只有在外面手动添加BeanFactoryPostProcessor,才会有数据                        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);                }                else {                        // Invoke factory processors registered with the context instance.                        // 若bfp没有继承bdrp则直接执行手动增加bf后置处理器的后置处理器                        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!                // 找到BeanFactoryPostProcessor实现类的BeanName数组                // 处理Spring自己的bf后置处理器                String[] postProcessorNames =                                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);                // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,                // Ordered, and the rest.                // PriorityOrdered的bf后置处理器集合                List priorityOrderedPostProcessors = new ArrayList<>();                // Ordered的bf后置处理器集合                List orderedPostProcessorNames = new ArrayList<>();                // 无PriorityOrdered无Ordered的bf后置处理器集合                List nonOrderedPostProcessorNames = new ArrayList<>();                //循环BeanName数组                for (String ppName : postProcessorNames) {                        //如果这个Bean被执行过了,跳过                        if (processedBeans.contains(ppName)) {                                // skip - already processed in first phase above                        }                        //如果实现了PriorityOrdered接口,加入到priorityOrderedPostProcessors                        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {                                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));                        }                        //如果实现了Ordered接口,加入到orderedPostProcessorNames                        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {                                orderedPostProcessorNames.add(ppName);                        }                        //如果既没有实现PriorityOrdered,也没有实现Ordered。加入到nonOrderedPostProcessorNames                        else {                                nonOrderedPostProcessorNames.add(ppName);                        }                }                // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.                //排序处理priorityOrderedPostProcessors,即实现了PriorityOrdered接口的BeanFactoryPostProcessor                sortPostProcessors(priorityOrderedPostProcessors, beanFactory);                //执行priorityOrderedPostProcessors                invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);                // Next, invoke the BeanFactoryPostProcessors that implement Ordered.                //执行实现了Ordered接口的BeanFactoryPostProcessor                List 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.                // 执行既没有实现PriorityOrdered接口,也没有实现Ordered接口的BeanFactoryPostProcessor                List 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...                // 清除了allBeanNamesByType&singletonBeanNamesByType()                // 清除缓存中的bd,因为后处理器可能有修改了原始元数据,例如替换值中的占位符                beanFactory.clearMetadataCache();        }

到此,关于"Java图解Spring启动时的后置处理器工作流程是什么"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0