当前位置: 首页 > news >正文

网站制作网站建设网站rss地址生成

网站制作网站建设,网站rss地址生成,效果好的网站建设公,响应式一页网站文章目录 一、简介1、BeanFactoryPostProcessor2、BeanPostProcessor 二、BeanFactoryPostProcessor 源码解析1、BeanDefinitionRegistryPostProcessor 接口实现类的处理流程2、BeanFactoryPostProcessor 接口实现类的处理流程3、总结 三、BeanPostProcessor 源码解析 一、简介… 文章目录 一、简介1、BeanFactoryPostProcessor2、BeanPostProcessor 二、BeanFactoryPostProcessor 源码解析1、BeanDefinitionRegistryPostProcessor 接口实现类的处理流程2、BeanFactoryPostProcessor 接口实现类的处理流程3、总结 三、BeanPostProcessor 源码解析 一、简介 Spring有两种类型的后置处理器分别是 BeanFactoryPostProcessor 和 BeanPostProcessor 这里再贴出我画的 Spring 启动过程可以看看这两种后置处理器在 Spring 启动过程中位置。 1、BeanFactoryPostProcessor BeanFactoryPostProcessor 的 postProcessBeanFactory 方法在 Spring 容器启动时被调用可以对整个容器中的 BeanDefinition Bean 定义进行处理BeanFactoryPostProcessor 还有个子接口 BeanDefinitionRegistryPostProcessor 其 postProcessBeanDefinitionRegistry 方法也可以对 BeanDefinition 进行处理的但两个的侧重点不一样 BeanDefinitionRegistryPostProcessor 侧重于创建自定义的 BeanDefinition而 BeanFactoryPostProcessor 侧重于对已有的 BeanDefinition 进行修改。 2、BeanPostProcessor BeanPostProcessor 是在 Bean 初始化方法调用前后对 Bean 进行一些预处理或后处理这个接口有两个方法分别是 postProcessBeforeInitialization 和 postProcessAfterInitialization分别用来执行预处理和后处理。 二、BeanFactoryPostProcessor 源码解析 处理 BeanFactoryPostProcessor 的源码在哪里呢我们先找到 Spring 的核心方法 refresh 方法在 AbstractApplicationContext 类里在里面找到 invokeBeanFactoryPostProcessors 方法 跟进去这个方法 在跟进到 PostProcessorRegistrationDelegate 类的 invokeBeanFactoryPostProcessors 方法里就到了核心处理逻辑了先列出这个方法的代码 public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListBeanFactoryPostProcessor beanFactoryPostProcessors) {// Invoke BeanDefinitionRegistryPostProcessors first, if any.SetString processedBeans new HashSet();if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry (BeanDefinitionRegistry) beanFactory;ListBeanFactoryPostProcessor regularPostProcessors new ArrayList();ListBeanDefinitionRegistryPostProcessor registryProcessors new ArrayList();for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor (BeanDefinitionRegistryPostProcessor) postProcessor;registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);}else {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.ListBeanDefinitionRegistryPostProcessor currentRegistryProcessors new ArrayList();// First, invoke the BeanDefinitionRegistryPostProcessors that implement 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);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// Next, invoke the BeanDefinitionRegistryPostProcessors that implement 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);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.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.invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);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!String[] postProcessorNames beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,// Ordered, and the rest.ListBeanFactoryPostProcessor priorityOrderedPostProcessors new ArrayList();ListString orderedPostProcessorNames new ArrayList();ListString 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)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.ListBeanFactoryPostProcessor 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.ListBeanFactoryPostProcessor 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(); }这段代码比较长我们可以分成两部分来看前半部分处理 BeanDefinitionRegistryPostProcessors 接口的实现类后半部分处理 BeanFactoryPostProcessor 接口的实现类我们先看 BeanDefinitionRegistryPostProcessors 接口的处理流程 1、BeanDefinitionRegistryPostProcessor 接口实现类的处理流程 首先创建了一个名叫 processedBeans 的 HashSet 是为了记录处理过的 PostProcessor 的名字目的是防止重复处理然后下面对 beanFactory 的类型进行了判断如果是 BeanDefinitionRegistry 类型会有一大段的处理逻辑如果不是就调用 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); 方法 if (beanFactory instanceof BeanDefinitionRegistry) {... }else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); }这个方法其实就是循环执行所有 PostProcessor 的 postProcessBeanFactory 方法我们再来看如果是 BeanDefinitionRegistry 类型是怎么处理的先看第一段 这一段是将传进来的参数 BeanFactoryPostProcessor 集合进行区分分成 BeanDefinitionRegistryPostProcessor 类型后面简称 BDRPP和非 BeanDefinitionRegistryPostProcessor 类型其实就是 BeanFactoryPostProcessor 类型后面简称 BFPP并执行了 BDRPP 类型的 postProcessBeanDefinitionRegistry 方法并且把两种类型分别添加到了两个集合里 registryProcessors 和 regularPostProcessors继续往下看 这一段先声明了一个 BDRPP 类型的集合用于存放在 Spring 容器里找到的 BDRPP然后从 Spring 容器里找到所有 BDRPP 的名字循环并找到实现了 PriorityOrdered 接口的 BDRPP排序添加到之前定义区分 BDRPP 和 BFPP 的集合 registryProcessors 里然后执行了这些实现了 PriorityOrdered 接口的 BDRPP 的 postProcessBeanDefinitionRegistry 方法下面以同样的方式处理实现了 Ordered 接口的 BDRPP这里先科普下 PriorityOrdered 和 Ordered PriorityOrdered 和 Ordered 是 Spring 框架中用于定义 Bean 的加载顺序的接口。而 PriorityOrdered 是 Ordered 的子类实现了这两个接口的类需要实现一个 getOrder() 方法返回一个 int 值这个值越大优先级就越低而实现了 PriorityOrdered 接口的 Bean 的加载顺序会优先于实现了 Ordered 接口的Bean且两者都优先于没实现这两个接口的 Bean 所以这里先处理的实现了 PriorityOrdered 接口的 BDRPP 再处理了实现了 Ordered 接口的 BDRPP 有的人会好奇哦为什么上面已经调用过一次 beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);下面为什么还要再调一次这不是重复代码了吗其实不是执行了 BDRPP 的 postProcessBeanDefinitionRegistry 方法有可能会产生新的 BDRPP 所以需要再重新取一次继续看下面的代码 知道了执行了 BDRPP 的 postProcessBeanDefinitionRegistry 方法有可能会产生新的 BDRPP 这段就好理解了一直循环获取 BDRPP执行其 postProcessBeanDefinitionRegistry 方法直到不产生新的 BDRPP 为止 最后因为 BDRPP 是 BFPP 的子类所以也是需要执行 BFPP 里的 postProcessBeanFactory 方法的但是 BDRPP 的先执行BFPP 的后执行。 到此 BDRPP 的处理完了下面看 BFPP 的 2、BeanFactoryPostProcessor 接口实现类的处理流程 看完 BeanDefinitionRegistryPostProcessor 之后BeanFactoryPostProcessor后面简称 BFPP的处理流程就比较简单了先看第一段代码 获取 Spring 容器里所有 BFPP 类型的 Bean然后分成三类分别是实现了 PriorityOrdered 接口的实现了 Ordered 接口的其他也就是不需要排序的这里需要注意因为获取 BFPP 类型的 Bean会将 BDRPP 类型的也获取到因为 BDRPP 是 BFPP 的子类嘛所以之前处理过的 BDRPP 需要跳过继续看下面 这边就很好理解了按照 PriorityOrdered Ordered 其他的顺序依次执行 postProcessBeanFactory 方法 3、总结 总结一下执行顺序 先执行了 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法按照顺序 PriorityOrdered Ordered 其他再执行了 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory 方法最后执行 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法按照顺序 PriorityOrdered Ordered 其他 三、BeanPostProcessor 源码解析 处理 BeanPostProcessor 后面简称 BPP的源码在哪里呢我们知道 BPP 是在 Bean 实例化过程中init 方法执行前后调用的入口在 Spring 的核心方法 refresh 方法中的 finishBeanFactoryInitialization(beanFactory); 方法里里面嵌套很多方法我们直接来到创建 Bean 的核心方法里也就是 AbstractAutowireCapableBeanFactory 类的 doCreateBean 方法在这个方法里找到 exposedObject initializeBean(beanName, exposedObject, mbd); 这句 在对 Bean 进行实例化和属性填充之后就会执行这个方法进一步完成 Bean 的初始化我们看看这个方法 ateBean方法在这个方法里找到exposedObject initializeBean(beanName, exposedObject, mbd); 这句 [外链图片转存中…(img-vnUdjdnd-1688632855515)] 在对 Bean 进行实例化和属性填充之后就会执行这个方法进一步完成 Bean 的初始化我们看看这个方法 [外链图片转存中…(img-3LXjab4Z-1688632855515)] 可以看到在执行 init 方法前后分别执行了 applyBeanPostProcessorsBeforeInitialization 和 applyBeanPostProcessorsAfterInitialization 方法这两个方法里循环了所有的 BPP调用了其 postProcessBeforeInitialization 和 postProcessAfterInitialization 方法。
http://www.zqtcl.cn/news/352305/

相关文章:

  • 西安市高新区建设规划局网站织梦小说网站模板下载地址
  • 网站开发简历 自我评价网页设计报告论文
  • 如何让网站不被收录不备案 国内网站
  • 站长之家域名买天猫店铺去哪里买
  • asp.net做的网站模板下载万网x3 wordpress
  • 设计网站设计目标天津市建设工程管理总队网站
  • 网站开始怎么做上海响应式网页建设
  • 网站备案 seo免费二维码制作网站
  • 删除网站备案网站建设湖南岚鸿建设
  • 做vlogger的网站有哪些长沙网站排名技巧
  • 媒体营销平台商品seo关键词优化
  • 芜湖先锋网站两学一做wordpress菜单顶部
  • 网站策划怎么样一级域名网站如何申请
  • 烟台高端网站开发网站开发哪个公司好
  • 广州网站定制开发方案南宁网站 制作
  • php做网站需要后台吗郑州建网站十大
  • 网站跳出率是什么意思百度服务
  • 建站 discuz开发者导航
  • 有哪些网站可以做毕业设计外贸网站发外链
  • 如何使用网站模板计算机培训班有用吗
  • 本地宁波网站建设电子商务网站建设工具都有那些
  • 网站建设的基本目标免费 wordpress企业主题
  • 专业网站建设微信商城开发规划馆网站建设
  • 网站建设公司沈阳西安建设工程信息交易中心官网
  • 青海住房和城乡建设部网站wordpress php7.3
  • 网站后台重置密码怎么做360网站怎么做网址链接
  • 广告网站建设及推广网站建设怎样推广
  • 做网站使网页不居中滁州注册公司流程和费用
  • 做网站广告经营者个性定制网站
  • 网站开发 北京外包公司软件公司网站建设