没啥好解释的,实际上InstantiationAwareBeanPostProcessor
的过程和它差不多,并且比它复杂 。
init-method的调用#// 调用before初始化Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 调用init-methodinvokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}
那么我们来查看invokeInitMethods
方法:
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {// 该Bean是否是initializingBean的实例boolean isInitializingBean = (bean instanceof InitializingBean);// 如果是 , 并且有`afterPropertiesSet`方法if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {// 调用afterPropertiesSet方法((InitializingBean) bean).afterPropertiesSet();}if (mbd != null && bean.getClass() != NullBean.class) {// 获取init-method名字String initMethodName = mbd.getInitMethodName();// 如果`initMethodName`不是空并且`initMethodName`并不和`afterPropertiesSet`同名且不是InitalizingBean(防止重复调用) , 并且Bean中实际有这个方法if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {// 调用initmethodinvokeCustomInitMethod(beanName, bean, mbd);}}}
所以,BeanFactory先是对于实现了InitializingBean
的Bean的afterPropertiesSet
进行调用,然后再对用户指定的init-method
进行调用 。
InitializingBean实战#@Datapublic class Workbench implements InitializingBean {@Autowiredprivate Person operator;@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("afterPropertiesSet");}}
结果:
afterPropertiesSetWorkbench(operator=Person(name=Yudoge))
init-method实战#添加init
方法
@Datapublic class Workbench implements InitializingBean {@Autowiredprivate Person operator;@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("afterPropertiesSet");}public void init() {System.out.println("init");}}
向BeanDefinition
中设置init方法名
// 设置Init方法名workbenchRbd.setInitMethodName("init");
结果
afterPropertiesSetinitWorkbench(operator=Person(name=Yudoge))
关于@PostConstruct#貌似BeanFactory并不支持@PostConstruct
,它好像是ApplicationContext通过预注册InstantiationAwareBeanPostProcessor
实现的 。这是我猜的 。
BeanPostProcessor.post初始化#略 , 因为前面已经讲了够多了 , 猜也能猜到怎么实现的
初始化阶段总结#
- 调用Aware方法
- 调用BeanPostProcessor的before初始化
- 如果是InitializingBean,调用afterPropertiesSet方法
- 如果有
init-method
,调用 - 调用BeanPostProcessor的after初始化
文章插图
回到
doCreateBean
方法中,最后,该方法判断了 , 如果必要的话就将该Bean注册到DisposableBean中:try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {}
我猜其中的逻辑就是看看该Bean是不是DisposableBean
的实例,如果是 , 注册到一个什么表中,方便销毁Bean时调用它的destory
方法 。我们先不管,先看BeanFactory中有没有什么
destroyBean
这种方法 。果然,在ConfigurableBeanFactory
中定义了这个方法 , AbstractBeanFactory
把它实现了:@Overridepublic void destroyBean(String beanName, Object beanInstance) {destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));}protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy();}
这里创建了一个什么DisposableBeanAdapter
,然后调用了destroy
方法,就没干别的了 。DisposableBeanAdapter#
DisposableBeanAdapter
的描述如下:/** * 实现了`DisposableBean`和`Runnable`的Adapter,对给定的Bean执行多个销毁步骤: * *- DestructionAwareBeanPostProcessors; *- 本身就实现了DisposableBean的Bean *- BeanDefinition中定义的Bean销毁方法 */class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 详解AQS中的condition源码原理
- 怎么去巴基斯坦去巴基斯坦时需要注意什么(从中国去巴基斯坦怎么去)
- 有到过伊拉克的人吗应该怎么去(从国内怎样到伊拉克)
- 从ObjectPool到CAS指令
- 蜘蛛的丝是从哪里吐出来的?
- .net 温故知新:【8】.NET 中的配置从xml转向json
- iqoo7电池多大_iqoo7电池多少毫安
- 【lwip】08-ARP协议一图笔记及源码实现
- <一>从指令角度了解函数堆栈调用过程
- 【lwip】07-链路层收发以太网数据帧源码分析