Spring的bean工厂后处理器和Bean后处理器
一、基本原理
1.1原理一
Spring 的后处理器是 Spring 对外开发的重要扩展点,允许我们介入到 Bean 的整个实例化流程中来,以达到动态注册
BeanDefinition,动态修改 BeanDefinition,以及动态修改 Bean 的作用。Spring 主要有两种后处理器:
BeanFactoryPostProcessor:Bean 工厂后处理器,在 BeanDefinitionMap 填充完毕,Bean 实例化之前执行;
BeanPostProcessor:Bean后处理器,一般在Bean实例化之后,填充到单例池 singletonObjects之前执行。
1.2原理二
BeanFactoryPostProcessor 是一个接口规范,实现了该接口的类只要交由 Spring 容器管理的话,那么 Spring 就会回调该接口的方法,用于对 BeanDefinition 注册和修改的功能。
publicinterfaceBeanFactoryPostProcessor{voidpostProcessBeanFactory(ConfigurableListableBeanFactorybeanFactory);}二、实验
2.1验证原理二
先定义一个类然后实现接口BeanFactoryPostProcessor,重写其方法postProcessBeanFactory
packagecom.itheima.processor;importorg.springframework.beans.BeansException;importorg.springframework.beans.factory.BeanFactory;importorg.springframework.beans.factory.config.BeanDefinition;importorg.springframework.beans.factory.config.BeanFactoryPostProcessor;importorg.springframework.beans.factory.config.ConfigurableListableBeanFactory;publicclassMyBeanFactoryPostProcessorimplementsBeanFactoryPostProcessor{@OverridepublicvoidpostProcessBeanFactory(ConfigurableListableBeanFactoryconfigurableListableBeanFactory)throwsBeansException{System.out.println("BeanFactoryMap填充完毕,回调改方法");}}将这个类在applicationContext.xml文件中配置成为bean:
<beanclass="com.itheima.processor.MyBeanFactoryPostProcessor"></bean>结果:
综上所述,原理二得证。
2.2实验二通过ConfigurableListableBeanFactory获取到BeanDefinition,然后修改权限名
packagecom.itheima.processor;importorg.springframework.beans.BeansException;importorg.springframework.beans.factory.BeanFactory;importorg.springframework.beans.factory.config.BeanDefinition;importorg.springframework.beans.factory.config.BeanFactoryPostProcessor;importorg.springframework.beans.factory.config.ConfigurableListableBeanFactory;publicclassMyBeanFactoryPostProcessorimplementsBeanFactoryPostProcessor{@OverridepublicvoidpostProcessBeanFactory(ConfigurableListableBeanFactoryconfigurableListableBeanFactory)throwsBeansException{System.out.println("BeanFactoryMap填充完毕,回调改方法");BeanDefinitionbeanDefinition=configurableListableBeanFactory.getBeanDefinition("userService");// 修改全限制名beanDefinition.setBeanClassName("com.itheima.service.impl.UserServiceImpl2");}}结果:
2.3实验三通过BeanDefinition添加全限制定名
上一个实验我们通过BeanDefinition实现了修改全限定名,那么本实验将实现添加全限制定名,通过前面的学习我们可以知道xml中的bean标签实际上是封装在一个BeanDefinition中的,然后又将BeanDefinition封装成一个map,使用时就直接遍历这个map,然后通过反射,最终是创建到单例池当的map中,调用getBean方法时则最终从该 Map 集合中取出 Bean 实例对象返回。详细可以看我的这篇博文[https://blog.csdn.net/2301_80749359/article/details/157357240?fromshare=blogdetail&sharetype=blogdetail&sharerId=157357240&sharerefer=PC&sharesource=2301_80749359&sharefrom=from_link]。
那么有添加全限定名,我们就需要创建一个BeanDefinition,下面是BeanDefinition的继承体系(选中BeanDefinition,按ctrl+h可以查看):
在开发过程中我们一般是使用RootBeanDefinition,所以直接new一个,然后再为其设置全限定名:
BeanDefinitionbeanDefinition=newRootBeanDefinition();beanDefinition.setBeanClassName("com.itheima.dao.impl.personDaoImpl");当有了BeanDefinition还不够,按照流程我们还要将其放到BeanDefinition的map中,如果直接运行我们会发现报错:
当然从错误信息我们不难发现是一个叫DefaultListableBeanFactory的类再调用getbean方法,这启发我们使用DefaultListableBeanFactory来进行注册BeanDefinition,而目前我们只有ConfigurableListableBeanFactory,所以考虑将其强转为它的子类,然后进行注册BeanDefinition到BeanDefinition的map中。
DefaultListableBeanFactorydefaultListableBeanFactory=(DefaultListableBeanFactory)configurableListableBeanFactory;defaultListableBeanFactory.registerBeanDefinition("personDao",beanDefinition);System.out.println(beanDefinition);增加完毕,撒花
^ <
✿✿✿✿✿✿✿✿✿✿✿✿✿✿✿
✿✿✿✿✿✿✿✿✿✿✿✿✿✿ ✿
✿✿✿✿✿✿✿✿✿✿✿✿✿✿✿