栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Spring源码】7. 如何添加自定义的BeanFactoryPostProcessor

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Spring源码】7. 如何添加自定义的BeanFactoryPostProcessor

放在前面的一段亲子鉴定...

关于BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcesso两人的关系声明—— 由下图可以看出BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,属父子关系

​还可以查看下族谱(类继承关系)

步骤:

  • 打开想要查看的类

  • 空白处右键

    • 注意⚠️右键的焦点要落在类的大括号里面(不然只会出现查看依赖的选项)

  • Diagrams->Show Diagram

  • 显示结果

​嘿嘿⊂((・⊥・))⊃实属父(BeanFactoryPostProcessor)子(BeanDefinitionRegistryPostProcessor)关系,鉴定完毕!

保姆级正文开始 1. 新建类

新建两个类,分别实现BeanFactoryPostProcessor接口和BeanDefinitionRegistryPostProcessor接口(任选一个也可以,本文为了介绍全面,两个同时举例)

MyBeanFactoryPostProcessor.java(实现BeanFactoryPostProcessor接口)

​

package com.aqin.custom.postprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;


public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      System.out.println("俺这是MyBeanFactoryPostProcessor.postProcessBeanFactory()W(`0`)W~");
   }
}
MyBeanDefinitionRegistryPostProcessor.java(实现BeanDefinitionRegistryPostProcessor接口)

package com.aqin.custom.postprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;


public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      System.out.println("俺这是MyRegistryPostProcessor.postProcessBeanFactory()( ´▽`)~");
   }

   @Override
   public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
      System.out.println("俺这是MyRegistryPostProcessor.postProcessBeanDefinitionRegistry()(*≧ω≦)~");
   }
}
2. 让Spring识别

方式主要有2种:

方式一:在配置文件中添加定义(让spring自动识别)

启动类:AqinApplication.java

package com.aqin;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Arrays;


public class AqinApplication {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
      System.out.println(Arrays.toString(context.getBeanDefinitionNames()));
   }
}

配置文件:applicationContext2.xml




   
   

测试查看输出结果:

方式二:重写customizeBeanFactory函数(用户手动添加)

新建ClassPathXmlApplicationContext的继承类

MyApplicationContext.java

package com.aqin.custom.postprocessor;

import org.springframework.context.support.ClassPathXmlApplicationContext;


public class MyApplicationContext extends ClassPathXmlApplicationContext {

   public MyApplicationContext(String... s) {
      super(s);
   }
}

修改启动类

package com.aqin;

import com.aqin.custom.postprocessor.MyApplicationContext;
import org.springframework.context.ApplicationContext;

import java.util.Arrays;


public class AqinApplication {
   public static void main(String[] args) {
      ApplicationContext context = new MyApplicationContext("applicationContext2.xml");
      System.out.println(Arrays.toString(context.getBeanDefinitionNames()));
   }
}

重写customizeBeanFactory函数

package com.aqin.custom.postprocessor;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class MyApplicationContext extends ClassPathXmlApplicationContext {

   public MyApplicationContext(String... s) {
      super(s);
   }

   @Override
   protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
      super.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
      super.addBeanFactoryPostProcessor(new MyBeanDefinitionRegistryPostProcessor());
   }
}

测试查看输出结果:

BBBBBBBBut、这两种方法有一点区别

来吧~总结下,不知道有没有同学注意到,我在启动类里都有一行输出

​System.out.println(Arrays.toString(context.getBeanDefinitionNames()));

其实就是spring上下文中的一个集合对象BeanDefinitionNames的输出,先啰嗦解释下BeanDefinitionNames这个集合(了解的同学可以直接跳过下面这段,或者瞅瞅哪里解释的不对评论区戳我~~)

spring在读取Bean后,会先将其转化成BeanDefinition(Bean定义),存入到BeanDefinitionMap和BeanDefinitionNames这两个集合中:

  • 其中BeanDefinitionMap是一个Map,key值存放字符串格式的BeanName(Bean的名称),value值存放BeanDefinition格式的Bean定义

  • BeanDefinitionNames是一个List,里面只存放了这些Bean的名称

拿DefaultListableBeanFactory举个例子,如下图,这两个集合在类DefaultListableBeanFactory中的定义:

然后我们分别查看两种方式的输出->

​虽然两种让spring发现方式新建类中的输出都被执行了,但是可以看到通过重写customizeBeanFactory函数进行扩展的spring上下文对象中的BeanDefinitionNames和BeanDefinitionMap都是空的,而通过配置文件让spring识别的则将我们在第一步新建的两个PostProcesscor都加了进去。

我们在通过Debug的方式仔细看下->

方式一:

方式二:

​总之~

就是后面那种我们在第一步新建的两个类虽然也都会执行,但是第二种方法是不会被当成spring的bean添加进BeanDefinitionMap和BeanDefinitionNames这两个集合中,这是两种方式的主要区别。

欢迎发现问题的同学(大佬)指教>>>让我们一起进步(=゚ω゚)ノ抱拳.gif

下一篇我们学习下我们本次新建的这些自定义PostProcessor是在哪里进行处理的(嘿嘿(*≧ω≦)没错、就是invokeBeanFactoryPostProcessors()~~~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/959041.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号