Spring扩展点之BeanFactoryPostProcessor
程序员文章站
2022-06-22 10:40:29
前言 接口是Spring中一个非常重要的接口,它的接口定义如下 当你实现了这个接口的时候,可以对还没有初始化的bean的属性进行修改或添加 注册 与 的统一注册不同, 的注册是留给具体的业务实现的。它的维护是在 类中 执行原理 调用逻辑在 方法中 这个方法比较长,可以重点关注我添加注释的地方 细心的 ......
前言
beanfactorypostprocessor
接口是spring中一个非常重要的接口,它的接口定义如下
public interface beanfactorypostprocessor { void postprocessbeanfactory(configurablelistablebeanfactory beanfactory) throws beansexception; }
当你实现了这个接口的时候,可以对还没有初始化的bean的属性进行修改或添加
beanfactorypostprocessor
注册
与beanpostprocessor
的统一注册不同,beanfactorypostprocessor
的注册是留给具体的业务实现的。它的维护是在abstractapplicationcontext
类中
private final list<beanfactorypostprocessor> beanfactorypostprocessors = new arraylist<>(); public void addbeanfactorypostprocessor(beanfactorypostprocessor postprocessor) { assert.notnull(postprocessor, "beanfactorypostprocessor must not be null"); this.beanfactorypostprocessors.add(postprocessor); }
执行原理
调用逻辑在abstractapplicationcontext.invokebeanfactorypostprocessors
方法中
这个方法比较长,可以重点关注我添加注释的地方
protected void invokebeanfactorypostprocessors(configurablelistablebeanfactory beanfactory) { postprocessorregistrationdelegate.invokebeanfactorypostprocessors(beanfactory, getbeanfactorypostprocessors()); if (beanfactory.gettempclassloader() == null && beanfactory.containsbean(load_time_weaver_bean_name)) { beanfactory.addbeanpostprocessor(new loadtimeweaverawareprocessor(beanfactory)); beanfactory.settempclassloader(new contexttypematchclassloader(beanfactory.getbeanclassloader())); } } public static void invokebeanfactorypostprocessors( configurablelistablebeanfactory beanfactory, list<beanfactorypostprocessor> beanfactorypostprocessors) { set<string> processedbeans = new hashset<string>(); // 1.判断beanfactory是否为beandefinitionregistry,在这里普通的beanfactory是defaultlistablebeanfactory,而defaultlistablebeanfactory实现了beandefinitionregistry接口,因此这边为true if (beanfactory instanceof beandefinitionregistry) { beandefinitionregistry registry = (beandefinitionregistry) beanfactory; list<beanfactorypostprocessor> regularpostprocessors = new linkedlist<beanfactorypostprocessor>(); list<beandefinitionregistrypostprocessor> registryprocessors = new linkedlist<beandefinitionregistrypostprocessor>(); // 2.处理入参beanfactorypostprocessors for (beanfactorypostprocessor postprocessor : beanfactorypostprocessors) { if (postprocessor instanceof beandefinitionregistrypostprocessor) { beandefinitionregistrypostprocessor registryprocessor = (beandefinitionregistrypostprocessor) postprocessor; // 如果是beandefinitionregistrypostprocessor则直接执行beandefinitionregistrypostprocessor接口的postprocessbeandefinitionregistry方法 registryprocessor.postprocessbeandefinitionregistry(registry); registryprocessors.add(registryprocessor); } else { regularpostprocessors.add(postprocessor); } } list<beandefinitionregistrypostprocessor> currentregistryprocessors = new arraylist<beandefinitionregistrypostprocessor>(); // 3找出所有实现beandefinitionregistrypostprocessor接口的bean的beanname string[] postprocessornames = beanfactory.getbeannamesfortype(beandefinitionregistrypostprocessor.class, true, false); for (string ppname : postprocessornames) { // 校验是否实现了priorityordered接口 if (beanfactory.istypematch(ppname, priorityordered.class)) { // 获取对应的bean实例, 添加到currentregistryprocessors中, currentregistryprocessors.add(beanfactory.getbean(ppname, beandefinitionregistrypostprocessor.class)); processedbeans.add(ppname); } } // 排序(根据是否实现priorityordered、ordered接口和order值来排序) sortpostprocessors(currentregistryprocessors, beanfactory); registryprocessors.addall(currentregistryprocessors); // 遍历currentregistryprocessors, 执行postprocessbeandefinitionregistry方法 invokebeandefinitionregistrypostprocessors(currentregistryprocessors, registry); // 清空currentregistryprocessors currentregistryprocessors.clear(); // 4.与上边3的流程差不多,这是这里处理的是实现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(); // 5.调用所有剩下的beandefinitionregistrypostprocessors boolean reiterate = true; while (reiterate) { reiterate = false; // 找出所有实现beandefinitionregistrypostprocessor接口的类 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); // 5遍历currentregistryprocessors, 执行postprocessbeandefinitionregistry方法 invokebeandefinitionregistrypostprocessors(currentregistryprocessors, registry); currentregistryprocessors.clear(); } // 6.调用所有beandefinitionregistrypostprocessor的postprocessbeanfactory方法 invokebeanfactorypostprocessors(registryprocessors, beanfactory); // 7.最后, 调用入参beanfactorypostprocessors中的普通beanfactorypostprocessor的postprocessbeanfactory方法 invokebeanfactorypostprocessors(regularpostprocessors, beanfactory); } else { invokebeanfactorypostprocessors(beanfactorypostprocessors, beanfactory); } // 到这里 , 入参beanfactorypostprocessors和容器中的所有beandefinitionregistrypostprocessor已经全部处理完毕, // 下面开始处理容器中的所有beanfactorypostprocessor // do not initialize factorybeans here: we need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // 8.找出所有实现beanfactorypostprocessor接口的类 string[] postprocessornames = beanfactory.getbeannamesfortype(beanfactorypostprocessor.class, true, false); // separate between beanfactorypostprocessors that implement priorityordered, // ordered, and the rest. // 用于存放实现了priorityordered接口的beanfactorypostprocessor list<beanfactorypostprocessor> priorityorderedpostprocessors = new arraylist<beanfactorypostprocessor>(); // 用于存放实现了ordered接口的beanfactorypostprocessor的beanname list<string> orderedpostprocessornames = new arraylist<string>(); // 用于存放普通beanfactorypostprocessor的beanname list<string> nonorderedpostprocessornames = new arraylist<string>(); // 8.1 遍历postprocessornames, 将beanfactorypostprocessor按实现priorityordered、实现ordered接口、普通三种区分开 for (string ppname : postprocessornames) { // 8.2 跳过已经执行过的 if (processedbeans.contains(ppname)) { // skip - already processed in first phase above } else if (beanfactory.istypematch(ppname, priorityordered.class)) { // 8.3 添加实现了priorityordered接口的beanfactorypostprocessor priorityorderedpostprocessors.add(beanfactory.getbean(ppname, beanfactorypostprocessor.class)); } else if (beanfactory.istypematch(ppname, ordered.class)) { // 8.4 添加实现了ordered接口的beanfactorypostprocessor的beanname orderedpostprocessornames.add(ppname); } else { // 8.5 添加剩下的普通beanfactorypostprocessor的beanname nonorderedpostprocessornames.add(ppname); } } // first, invoke the beanfactorypostprocessors that implement priorityordered. // 9.调用所有实现priorityordered接口的beanfactorypostprocessor // 9.1 对priorityorderedpostprocessors排序 sortpostprocessors(priorityorderedpostprocessors, beanfactory); // 9.2 遍历priorityorderedpostprocessors, 执行postprocessbeanfactory方法 invokebeanfactorypostprocessors(priorityorderedpostprocessors, beanfactory); // next, invoke the beanfactorypostprocessors that implement ordered. // 10.调用所有实现ordered接口的beanfactorypostprocessor list<beanfactorypostprocessor> orderedpostprocessors = new arraylist<beanfactorypostprocessor>(); for (string postprocessorname : orderedpostprocessornames) { // 10.1 获取postprocessorname对应的bean实例, 添加到orderedpostprocessors, 准备执行 orderedpostprocessors.add(beanfactory.getbean(postprocessorname, beanfactorypostprocessor.class)); } // 10.2 对orderedpostprocessors排序 sortpostprocessors(orderedpostprocessors, beanfactory); // 10.3 遍历orderedpostprocessors, 执行postprocessbeanfactory方法 invokebeanfactorypostprocessors(orderedpostprocessors, beanfactory); // finally, invoke all other beanfactorypostprocessors. // 11.调用所有剩下的beanfactorypostprocessor list<beanfactorypostprocessor> nonorderedpostprocessors = new arraylist<beanfactorypostprocessor>(); for (string postprocessorname : nonorderedpostprocessornames) { // 11.1 获取postprocessorname对应的bean实例, 添加到nonorderedpostprocessors, 准备执行 nonorderedpostprocessors.add(beanfactory.getbean(postprocessorname, beanfactorypostprocessor.class)); } // 11.2 遍历nonorderedpostprocessors, 执行postprocessbeanfactory方法 invokebeanfactorypostprocessors(nonorderedpostprocessors, beanfactory); // clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... // 12.清除元数据缓存(mergedbeandefinitions、allbeannamesbytype、singletonbeannamesbytype), // 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符... beanfactory.clearmetadatacache(); }
细心的同学可能会发现上方还出现了一个beandefinitionregistrypostprocessor
,这个东东其实是beanfactorypostprocessor
的特殊实习,观察调用它的方法可以看到它需要一个参数:beandefinitionregistry
,通过这个参数可以更为方便的去做一些自定义bean的操作
总结一下上方的逻辑:
- 将
beanfactorypostprocessor
和beandefinitionregistrypostprocessor
,分别放入两个集合 - 分别进行排序处理
- 按照优先级分别调用
invokebeandefinitionregistrypostprocessors
和invokebeanfactorypostprocessors
方法 - 这两个invoke方法相信你可以想象的到无非就是循环调用这些实现类对应的方法
spring的实现
查看这个接口的继承体系,可以看到这个接口的实现类是非常多的,各个实现类的功能如果感兴趣大家可以去慢慢挖掘一下
下一篇: ZooKeeper 面试题
推荐阅读
-
Spring扩展点之Aware接口族
-
如何利用Spring的@Import扩展点与spring进行无缝整合
-
Java基础之MapReduce框架总结与扩展知识点
-
iOS开发之c语言基础 扩展知识点 及 企业面试题
-
Spring扩展点之FactoryBean接口
-
Spring扩展点之BeanFactoryPostProcessor
-
我的spring学习笔记15-容器扩展点之PropertyOverrideConfigurer
-
我的spring学习笔记14-容器扩展点之PropertyPlaceholderConfigurer
-
Spring Ioc 容器扩展点3 使用FactoryBean自定义初始化逻辑
-
spring源码扩展点二:customizeBeanFactory方法