接口简介

beanfactorypostprocessor 接口是 spring 初始化 beanfactory 时对外暴露的扩展点,spring ioc 容器允许 beanfactorypostprocessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。

beandefinitionregistrypostprocessor 继承自 beanfactorypostprocessor,比 beanfactorypostprocessor 具有更高的优先级,主要用来在常规的 beanfactorypostprocessor 检测开始之前注册其他 bean 定义。特别是,你可以通过 beandefinitionregistrypostprocessor 来注册一些常规的 beanfactorypostprocessor,因为此时所有常规的 beanfactorypostprocessor 都还没开始被处理。

注意点:通过beandefinitionregistrypostprocessor 注册的 beandefinitionregistrypostprocessor 接口的postprocessbeandefinitionregistry方法将得不到调用,具体的原因会在下面的代码中解释。

beanfactorypostprocessor 接口调用机制

beanfactorypostprocessor 接口的调用在 abstractapplicationcontext#invokebeanfactorypostprocessors方法中。

protected void invokebeanfactorypostprocessors(configurablelistablebeanfactory beanfactory) {
		postprocessorregistrationdelegate.invokebeanfactorypostprocessors(beanfactory, getbeanfactorypostprocessors());

		// detect a loadtimeweaver and prepare for weaving, if found in the meantime
		// (e.g. through an @bean method registered by configurationclasspostprocessor)
		if (beanfactory.gettempclassloader() == null && beanfactory.containsbean(load_time_weaver_bean_name)) {
			beanfactory.addbeanpostprocessor(new loadtimeweaverawareprocessor(beanfactory));
			beanfactory.settempclassloader(new contexttypematchclassloader(beanfactory.getbeanclassloader()));
		}
	}

进入postprocessorregistrationdelegate.invokebeanfactorypostprocessors(beanfactory, getbeanfactorypostprocessors())方法:

public static void invokebeanfactorypostprocessors(
			configurablelistablebeanfactory beanfactory, list<beanfactorypostprocessor> beanfactorypostprocessors) {
   // 用于存放已经处理过的bean名字
		set<string> processedbeans = new hashset<>();
   // 一般会进入这个判断
		if (beanfactory instanceof beandefinitionregistry) {
			beandefinitionregistry registry = (beandefinitionregistry) beanfactory;
    // 所谓的regularpostprocessors就是指实现beanfactorypostprocessor接口的bean
			list<beanfactorypostprocessor> regularpostprocessors = new arraylist<>();
    // 所谓的registryprocessors就是指实现beandefinitionregistrypostprocessor接口的bean
			list<beandefinitionregistrypostprocessor> registryprocessors = new arraylist<>();
    // 这边遍历的是通过applicationcontext接口注册的beanfactorypostprocessor和beandefinitionregistrypostprocessor接口
    // 需要和beanfactory中beandefinitionmap中的beanfactorypostprocessor接口区分开
			for (beanfactorypostprocessor postprocessor : beanfactorypostprocessors) {
				if (postprocessor instanceof beandefinitionregistrypostprocessor) {
					beandefinitionregistrypostprocessor registryprocessor =
							(beandefinitionregistrypostprocessor) postprocessor;
      //如果是beandefinitionregistrypostprocessor,则先进行postprocessbeandefinitionregistry处理,这个方法一般进行beandefinition注册,从这边可以看出beandefinitionregistrypostprocessor接口的方法先调用,所以优先级高于beanfactorypostprocessor
      // 通过这个代码可以看出,通过applicationcontext直接注册的beanfactorypostprocessor和beandefinitionregistrypostprocessor并不支持order接口,而是根据注册的顺序执行
					registryprocessor.postprocessbeandefinitionregistry(registry);
      // 保存这个beandefinitionregistrypostprocessor,因为还要执行这个类的beanfactorypostprocessor方法;
					registryprocessors.add(registryprocessor);
				}
				else {
      // 保存,后面还要执行这个类的beanfactorypostprocessor方法;
					regularpostprocessors.add(postprocessor);
				}
			}

			list<beandefinitionregistrypostprocessor> currentregistryprocessors = new arraylist<>();
    // 这边获取的是beanfactory中的beandefinitionregistrypostprocessor
			string[] postprocessornames =
					beanfactory.getbeannamesfortype(beandefinitionregistrypostprocessor.class, true, false);
			for (string ppname : postprocessornames) {
     //先处理priorityordered标注的beandefinitionregistrypostprocessor
				if (beanfactory.istypematch(ppname, priorityordered.class)) {
					currentregistryprocessors.add(beanfactory.getbean(ppname, beandefinitionregistrypostprocessor.class));
      //将其标记为已经处理,防止重复处理
					processedbeans.add(ppname);
				}
			}
    // 将其排序,以便按顺序处理
			sortpostprocessors(currentregistryprocessors, beanfactory);
    // 将其保存,以便处理这个类的beanfactorypostprocessor方法
			registryprocessors.addall(currentregistryprocessors);
    // 执行beandefinitionregistrypostprocessor接口方法
			invokebeandefinitionregistrypostprocessors(currentregistryprocessors, registry);
    // 清除,以便开始处理@order标注的注解
			currentregistryprocessors.clear();
  
    // 注意:这边重新获取beandefinitionregistrypostprocessor是有深意的,因为上面在处理@priorityordered标注的beandefinitionregistrypostprocessor时可能又注入了新的beandefinitionregistrypostprocessor。
			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();

    // 处理不标注注解的beandefinitionregistrypostprocessor
			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();
			}

			// 调用postprocessbeanfactory 方法,所以beandefinitionregistrypostprocessor中的postprocessbeanfactory方法的优先级要高。
			invokebeanfactorypostprocessors(registryprocessors, beanfactory);
			invokebeanfactorypostprocessors(regularpostprocessors, beanfactory);
		}

		else {
			// invoke factory processors registered with the context instance.
			invokebeanfactorypostprocessors(beanfactorypostprocessors, beanfactory);
		}

		// 开始处理beanfactorypostprocessor接口
		string[] postprocessornames =
				beanfactory.getbeannamesfortype(beanfactorypostprocessor.class, true, false);

		// 也是按照@priorityordered @ordered 和普通的方式进行处理
		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);
			}
		}
   // 先执行@priorityordered标注的接口
		sortpostprocessors(priorityorderedpostprocessors, beanfactory);
		invokebeanfactorypostprocessors(priorityorderedpostprocessors, beanfactory);
   // 处理@order标注的类
		list<beanfactorypostprocessor> orderedpostprocessors = new arraylist<>(orderedpostprocessornames.size());
		for (string postprocessorname : orderedpostprocessornames) {
    // 这边通过名字重新拿了bean,应该是怕上面的处理改变了bean
			orderedpostprocessors.add(beanfactory.getbean(postprocessorname, beanfactorypostprocessor.class));
		}
		sortpostprocessors(orderedpostprocessors, beanfactory);
		invokebeanfactorypostprocessors(orderedpostprocessors, beanfactory);

		// 最后调用普通的beanfactorypostprocessor
		list<beanfactorypostprocessor> nonorderedpostprocessors = new arraylist<>(nonorderedpostprocessornames.size());
		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();
	}

简单总结

上面的方法看起来很长很复杂,但其实干的事情并不多,就调用了beanfactorypostprocessor和beandefinitionregistrypostprocessor接口的实现。这边再简单总结下具体的过程:

step1:执行通过applicationcontext#addbeanfactorypostprocessor()方法注册的beanfactorypostprocessor和beandefinitionregistrypostprocessor。

具体过程如下:假如通过applicationcontext注册了一个beanfactorypostprocessor和beandefinitionregistrypostprocessor,那么会先执行beandefinitionregistrypostprocessor的postprocessbeandefinitionregistry方法,但是beandefinitionregistrypostprocessor的postprocessbeanfactory方法和beanfactorypostprocessor的postprocessbeanfactory方法暂时都不会在这步执行。

另外需要注意的是:通过applicationcontext注册的beanfactorypostprocessor和beandefinitionregistrypostprocessor都不支持@priorityordered和@ordered顺序处理,而是按照我们添加的顺序处理

step2:处理beanfactory中的beandefinitionregistrypostprocessor,处理的顺序是先处理@priorityordered标注的,再处理@ordered标注的,最后处理普通的beandefinitionregistrypostprocessor。到这边,所有beandefinitionregistrypostprocessor接口的postprocessbeandefinitionregistry方法都已经调用完毕,下面就开始处理beanfactorypostprocessor的postprocessbeanfactory方法。

step3:调用beandefinitionregistrypostprocessor实现的postprocessbeanfactory方法(因为beandefinitionregistrypostprocessor是beanfactorypostprocessor的子接口)

step4:调用通过applicationcontext#addbeanfactorypostprocessor()注册的“单纯”的beanfactorypostprocessor

step5:调用beanfactory中的beanfactorypostprocessor,调用顺序也是按照@priorityordered和@ordered顺序处理,没有这两个注解的最后处理。

好了,到这边beanfactorypostprocessor和beandefinitionregistrypostprocessor接口就已经处理完了。后面我们会拿configurationclasspostprocessor 这个特殊的beandefinitionregistrypostprocessor做列子讲下具体流程,这边只是介绍beanfactorypostprocessor的调用机制。

到此这篇关于spring的beanfactorypostprocessor接口的文章就介绍到这了,更多相关spring beanfactorypostprocessor接口内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!