这篇文章主要介绍“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(); } } }
该方法主要做启动前的准备工作:记录启动时间,活动标记为启动以及环境属性变量集合的初始化;
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<>(); }
主要是获取context上下文中的bean工厂;
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // CAS保证同步 refreshBeanFactory(); // 返回beanFactory- DefaultListableBeanFactory.class ConfigurableListableBeanFactory beanFactory = getBeanFactory(); return beanFactory; }
做一些准备工作,添加了两个后置处理器ApplicationContextAwareProcessor
和ApplicationListenerDetector
;
设置了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()); } }
执行自定义的BeanFactoryProcessor
和内置的BeanFactoryProcessor
;
getBeanFactoryPostProcessors()
方法是我们手动通过执行addBeanFactoryPostProcessor(XX)
设置自定义的后置处理器。如果初始化执行到这,没有手动增加后置处理器的话,那么此时List<BeanFactoryPostProcessor>
的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()
方法,从而去扫描并执行BeanFactoryProcessor
和BeanDefinitionRegistryPostProcessor
;
我们通过继承关系看,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()
;
上面的已经执行完了:
手动添加的后置处理器的bdrf. postProcessBeanDefinitionRegistry()
和bfp.postProcessBeanFactory()
;
内置的bdrp. postProcessBeanDefinitionRegistry()
取出内置的bfp,分为实现了PriorityOrdered
, Ordered
和都没有实现的三类;
目前这里内置的有两个。但其中config上面已经执行过了,此处只执行下方的一个;
将上面三类直接执行bfp. postProcessBeanDefinitionRegistry()
;
清除缓存中的bd,因为后处理器可能有修改了原始元数据,例如替换值中的占位符;
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); // 如果不是BeanDefinitionRegistry 则直接执行beanFactoryPostProcessors // 刚启动时传入的beanFactory是DefaultListableBeanFactory,他是实现了BeanDefinitionRegistry 因此会走这里 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // bf后置处理器集合(手动添加与bdr后置处理器集合【下面的那个集合】):因为bdrp属于bfp List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); // bdr后置处理器集合(手动添加与spring自己的) List<BeanDefinitionRegistryPostProcessor> 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<BeanDefinitionRegistryPostProcessor> 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<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); // Ordered的bf后置处理器集合 List<String> orderedPostProcessorNames = new ArrayList<>(); // 无PriorityOrdered无Ordered的bf后置处理器集合 List<String> 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<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. // 执行既没有实现PriorityOrdered接口,也没有实现Ordered接口的BeanFactoryPostProcessor 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... // 清除了allBeanNamesByType&singletonBeanNamesByType() // 清除缓存中的bd,因为后处理器可能有修改了原始元数据,例如替换值中的占位符 beanFactory.clearMetadataCache(); }
到此,关于“Java图解Spring启动时的后置处理器工作流程是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。