上篇聊完了bean的解析,说起来做的事情很简单,把xml文件里面配置的标签全部解析到spring容器里面,但是spring做的时候,花了那么大代价去做,后面看看到底值不值得呢。

接下来看看prepareBeanFactory(beanFactory)方法,点进去看一下:

public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();

if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

//1.调用实现了PriorityOrdered 的BeanDefinitionRegistryPostProcessors
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

//2.调用实现了Ordered 的BeanDefinitionRegistryPostProcessors
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

//3.调用其他剩余的BeanDefinitionRegistryPostProcessors
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}

//4.调用所有实现了BeanFactoryPostProcessor类并重写了postProcessBeanFactory方法的回调
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}

else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}

我的天哪,又是这么长的代码,仔细一看,好多重复的代码,这块重复的代码封装一下是不是很完美(小声bb),仔细分析之后(主要还是靠之前的大牛们写的博客),其实做的主要就是4件事:

1.调用实现了PriorityOrdered 的BeanDefinitionRegistryPostProcessors
2.调用实现了Ordered 的BeanDefinitionRegistryPostProcessors
3.调用其他剩余的BeanDefinitionRegistryPostProcessors
4.调用所有实现了BeanFactoryPostProcessor类并重写了postProcessBeanFactory方法的回调
我们首先看前三步调用的BeanDefinitionRegistryPostProcessors是在干啥,核心代码其实就是上面标红的代码,点进去:
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}

这块只做了一个遍历,然后调用postProcessBeanDefinitionRegistry方法,这个方法又是干啥的呢,点进去是一个抽象类,我们先不管这个是干嘛的,看一下我写的一个类:

@Component
public class BeanDefinitionTest implements BeanDefinitionRegistryPostProcessor {

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
genericBeanDefinition.setBeanClass(BeanClass.class);

// genericBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(null);

MutablePropertyValues propertyValues = genericBeanDefinition.getPropertyValues();
propertyValues.addPropertyValue("username","peter");

registry.registerBeanDefinition("beanClass",genericBeanDefinition);

}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println(beanFactory.getBean("beanClass"));
}
}

可以看到BeanDefinitionTest实现了 BeanDefinitionRegistryPostProcessor ,我重写了BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法和BeanFactoryPostProcessor的postProcessBeanFactory方法,你会发现其实上面前3步调用的方法和第4步调用的方法,就是我这边重写的两个方法,感兴趣的同学可以自己写一下,启动容器的时候debug看看。那么这两个方法是做什么的呢,不知道还记不记得前面注册beanDefinition的时候,其实就是用BeanDefinitionRegistry 注册的。而beanFactory是存储所有beanDefinition对象的容器,拿到它就相当于拿到了所有的beanDefinition对象。好像还是很厉害的,实现了这一个方法,既可以添加自定义的bean,又可以自己修改已经有的bean对象,spring大法牛逼。

接下来再看一下beanPostProcessor的注册:

public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

//1.注册实现了PriorityOrdered的beanPostProcessor
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

//2.注册实现了Ordered的beanPostProcessor
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);

//3.注册没用实现排序的beanPostProcessor
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

//4.重新注册所有的的beanPostProcessor
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);

// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

主要还是分为4步:

1.注册实现了PriorityOrdered的beanPostProcessor

2.注册实现了Ordered的beanPostProcessor

3.注册没有实现排序接口的beanPostProcessor

4.重新注册所有的的beanPostProcessor

而注册的具体逻辑又分为几步:

1.getBean获取BeanProcessor实例

2.加入容器

3.排序后注册

在这里,很多我们后面aop或者其他地方需要用的到处理器类就都已经实例化完成了,刚开始接触的时候都说这叫bean的后置处理器,因此,一直纠结于在bean实例化完成后才会去执行,可实际研究源码的时候,发现并不是我想的这样,因此困扰了很久。

其实就是一个处理器类吧,在bean初始化前后都会去调用,让我们自己去做一些定制化的修改,而且可以实现排序接口,实现执行的先后顺序。

总结:

        刚开始接触spring源码的时候,这块的源码总是无法理解,因为脑子里面的固有思维是spring做的肯定是去加载,注册,实例化bean的,对于框架的拓展性,高可用没有什么概念,像这个方法里面基本上除了为了提前能调用到我添加的类,会去调用getBean方法提前实例化,其他的基本都是为了让使用者可以更自由的去拓展。我想,以后在我自己去写代码的时候,也会去多考虑这些吧。

最新文章

  1. JSON认识
  2. sql 第 10条 到20条
  3. SQL Server 2008 建立分区表 脚本
  4. 关于Bean
  5. linux kernel 模块多文件编译
  6. Meth | ubuntu下安装与卸载软件方法
  7. jquery 获取自定义属性(attr 和 prop的区别)
  8. 11.4.2 排序或合并文件(sort命令) - 51CTO.COM
  9. ajax 写登录
  10. 《Spark大数据处理:技术、应用与性能优化》【PDF】 下载
  11. ArcGIS Server较早版本切片迁移注意事项
  12. Java 中的按值传递
  13. An Introduction to OAuth 2
  14. mysql视图和临时表的区别
  15. CF1100B Build a Contest
  16. JAVA SpringBoot 项目打成jar包供第三方引用自动配置(Spring发现)解决方案
  17. jenkins执行shell提示命令不存在
  18. JS进阶系列之this
  19. web中显示中文名称的图片,可以这样配置filter
  20. springmvc @valid

热门文章

  1. C#中RDLC报表判断某字段的值为null
  2. EF快速入门--直接修改(简要介绍ObjectContext处理机制)
  3. docker 使用教程1
  4. Git 常用命令 【13个命令包含git 90%的操作】
  5. CTF:从0到1 -&gt; zero2one
  6. JAVA数据结构(十一)—— 堆及堆排序
  7. UML第二次结对作业
  8. CountDownLatch/CyclicBarrier/Semaphore 使用过吗
  9. netty核心组件之channel、handler、ChannelHandlerContext、pipeline
  10. 记一次Goroutine与wg导致的问题