所以,resolveBeforeInstantiation
方法应该就是查找那些InstantiationAwareBeanPostProcessor
,然后调用它们 。
InstantiationAwareBeanPostProcessor的before hook#protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {// 应用BeanPostProcessor的beforeInstantiationbean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {// 调用BeanPostProcessors的初始化后方法,注意是初始化后不是实例化后// 前提是before方法返回了一个对象bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;}
我们可以看到,这个方法的代码非常简单,虽然还没写明,但是99%就是调用所有的InstantiationAwareBeanPostProcessor
了,两个apply
应该就是做这个工作的 。我们不妨点进去看一个:
@Nullableprotected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {return result;}}return null;}
这不就是对所有的InstantiationAwareBeanPostProcessor
进行遍历调用吗,取第一个返回结果的Processor的结果 。大家说,这里用到了什么设计模式??
InstantiationAwareBeanPostProcessor before hook的使用#下面,我们自己创建一个实现类,它的功能就是打印所有进来的Bean名字和类型:
public class MyInstantiationProcessor implements InstantiationAwareBeanPostProcessor {@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {System.out.println("[+] > MyInstantiationProcessor before bean instantiation : " + beanName + " => " + beanClass.getName());return null;}}
下面,我们把它设置到BeanFactory中,然后尝试获取Bean:
factory.addBeanPostProcessor(new MyInstantiationProcessor());Workbench workbench = factory.getBean(Workbench.class);System.out.println(workbench);
输出:
[+] > MyInstantiationProcessor before bean instantiation : workbench => top.yudoge.springserials.basic.beanfactory.beans.Workbench[+] > MyInstantiationProcessor before bean instantiation : person => top.yudoge.springserials.basic.beanfactory.beans.PersonWorkbench(operator=Person(name=Yudoge))
因为Workbench
对象依赖Person
对象,所以引起了两个对象的连锁创建,最后一行我们得到了Workbench
对象 。
下面我们尝试让BeanPostProcessor针对Person类返回一个另外的Bean,而不是null
:
public class MyInstantiationProcessor implements InstantiationAwareBeanPostProcessor {@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {System.out.println("[+] > MyInstantiationProcessor before bean instantiation : " + beanName + " => " + beanClass.getName());if (beanClass.getName().equals(Person.class.getName())) {return new Person("我是MyInstantiationProcessor返回的Person");}return null;}}
运行:
[+] > MyInstantiationProcessor before bean instantiation : workbench => top.yudoge.springserials.basic.beanfactory.beans.Workbench[+] > MyInstantiationProcessor before bean instantiation : person => top.yudoge.springserials.basic.beanfactory.beans.PersonWorkbench(operator=Person(name=我是MyInstantiationProcessor返回的Person))
成功的返回了我们创建出来的Person 。
经验总结扩展阅读
- 2023年农历八月初一砍树吉日 2023年9月15日砍树好吗
- 2023年9月15日买宠物好不好 2023年9月15日买宠物好吗
- 2023年9月15日是买狗的黄道吉日吗 2023年9月15日买狗黄道吉日
- 2023年9月15日买猫行吗 2023年9月15日是买猫吉日吗
- 2023年1月28日买牛好吗 2023年1月28日是买牛吉日吗
- 2023年农历八月初一买鸡吉日 2023年9月15日买鸡好不好
- 2023年9月15日是买鸭吉日吗 2023年农历八月初一买鸭吉日
- 2023年农历正月初七买猫吉日 2023年1月28日适合买猫吗
- 2023年农历正月初七宜砍树吗 2023年1月28日砍树吉日一览表
- 2023年1月28日适合塑绘吗 2023年1月28日塑绘黄道吉日