接口简介
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!