type
status
date
slug
summary
tags
category
icon
password
这里写文章的前言:
一个简单的开头,简述这篇文章讨论的问题、目标、人物、背景是什么?并简述你给出的答案。
可以说说你的故事:阻碍、努力、结果成果,意外与转折。
📝 Spring扩展
前面讲到了这么多的什么BeanPostProcessor,事件什么的. 如果不写几下代码这里怕是很难弄清楚是个怎么回事. 所以只有看到代码跑,就大致可以看到其效果还是很明显的.
BeanFactoryPostProcessor
我们这里实现一下 BeanFactoryPostProcessor 来看一下效果
我们就写一个简单的类, 然后实现下接口 BeanFactoryPostProcessor, 我们这里就获取下 beanFactory中的所有beanDefinitionNames的数组,然后给打印出来看效果. 可以看下下面打印的接口. 然后我们看下源码怎么执行的
直接看这个类的这个方法,我这里只截取了一部分代码,也就是和 BeanFactoryPostProcessor 有关的代码. 和它没关系的代码,这里就没有去截取了
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)
看源码看是如何调用到这个方法的,还是比较好理解。先是根据 BeanFactoryPostProcessor.class获取出beanName的集合,然后老规矩进行一些特定的排序,当然我这里什么都没做,也就是最后处理哦
然后跟到invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);这个方法里面,可以看到它迭代这个集合的元素,当然了,我们只需要关注我们自己定义的哪个就可以了,然后就会走其postProcessBeanFactory方法,也就是走到了我们定义的类的这个方法上来了
OK啦。大致流程就是这个样子的,还是比较好理解的
BeanPostProcessor
我们先写一个 Bean. 然后可以里面写一个属性,方便标识
然后我们自定义一个BeanPostProcessor,其实现了BeanPostProcessor接口
可以看到的是,我们在if中做了beanName的判断,如果是的话,那么我们就会强转,然后给name字段赋值上GavinYang的值.
我们给断点打到 if这里,然后看进来的堆栈信息,发现其是在初始化bean中,然后调用beanPostProcessor的postProcessAfterInitialization的方法才会走到这里,也就是在doCreateBean这个方法里面.
然后这个 YangBeanPostProcessor 是什么时候给添加到 beanFactory中去的呢?
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)在这个方法打上断点,然后你会发现其get出来的postProcessorNames数组,就有我们的这个YangBeanPostProcessor,然后走registerBeanPostProcessors方法的时候,就会给添加到beanFactory中去.
启动类 :
然后我们这里用一个启动类.
这就打印出来的结果就可以看到的是GavinYang,也就是说我们初始化这个bean之后,然后给其name属性赋值上了GavinYang这个值
Lifecycle 扩展
Lifecycle 扩展要比起 BeanPostProcessor要好理解得多,因为你只用去实现这个接口(SmartLifecycle),然后在org.springframework.context.support.AbstractApplicationContext#finishRefresh到这个方法的时候,就会去调用实现这个接口的对用的方法.
这里我们自己写一个类,然后实现 SmartLifecycle 接口即可。
可以看到下面的打印参数.还是很清楚的明白.
然后我们再看下源码,为什么要实现 SmartLifecycle 这个接口呢?
org.springframework.context.support.DefaultLifecycleProcessor
这里我们先看到 phases ,也就是最底下的代码, 这个集合是有值的情况下先排序,然后再迭代,然后调用到 start()方法, 这个start方法是不是在我们的实现类中可以看到,是不是非常的熟悉感觉.
然后我们在看下,怎么样让这个集合能有值呢?
phases.put(phase, group); 可以看到 put方法这里, autoStartupOnly 是false 或者bean是SmartLifecycle的子类,并且其isAutoStartup方法的是true. 点到SmartLifecycle源码中去看,可以发现这个方法默认是返回的true.
接着在调用getPhase方法, 该方法也就是判断.最最关键的phases集合来了,先从里面get出数据,然后判断数据是不是null,如果是null的话,就先new一个Group出来,然后调用phases的put方法,也就是放入到这个集合中去了
所以这里就是我们为什么要实现 SmartLifecycle 这个接口,就会有启动的效果了的原因.
🤗 总结归纳
总结文章的内容
📎 参考文章
- 一些引用
- 引用文章
有关文章的问题,欢迎您在底部评论区留言,一起交流~