spring源码分析——BeanPostProcessor接口

 

  BeanPostProcessor是处理bean的后置接口,beanDefinitionMaps中的BeanDefinition实例化完成后,完成populateBean,属性设置,完成

初始化后,这个接口支持对bean做自定义的操作。

一:BeanPostProcessor的使用

定义一个测试用的model对象,name属性默认为hello

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class BeanDemo {
 
    private String name = "hello";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("BeanDemo{");
        sb.append("name='").append(name).append('\'');
        sb.append('}');
        return sb.toString();
    }
}

  

自定义一个MyBeanPostProcessor类,实现BeanPostProcessor接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Service
public class MyBeanPostProcessor implements BeanPostProcessor {
 
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }
 
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(beanName.equals("beanDemo")){
            BeanDemo beanDemo = (BeanDemo)bean;
            beanDemo.setName("kitty");
            return beanDemo;
        }
        return bean;
    }
}

  

 

 

从运行结果看,spring中维护的beanName为beanDemo的对象,name属性为ketty

 

 

二:看看源码怎么实现的

1:实例化并且注册到beanPostProcessors集合中

 

 

 

 

主要的实例化逻辑在这个接口,这个接口的作用就是把所有实现BeanPostProcessor接口的类实例化,然后注册到 beanPostProcessors这个缓存中

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
public static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
 
    // 获取所有实现接口BeanPostProcessor的beanName
    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.
    /**
     * 把实现PriorityOrdered 和 Ordered 和 其他的处理器分开
     */
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    /**
     * 1:遍历集合postProcessorNames
     * 2:判断类型,如果是PriorityOrdered,则实例化对象放入priorityOrderedPostProcessors集合,
     * Ordered 则放入orderedPostProcessorNames集合,其他的放入nonOrderedPostProcessorNames集合
     */
    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);
        }
    }
 
    // First, register the BeanPostProcessors that implement PriorityOrdered.
    // 首先对priorityOrderedPostProcessors集合中实例对象排序,然后注册,放入beanFactory中缓存下来
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
 
    // Next, register the BeanPostProcessors that implement Ordered.
    // 然后再实例化实现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);
 
    // 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);
 
    // Finally, re-register all internal BeanPostProcessors.
    // 最后再次注册内部postProcessor
    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));
}

  

 

 

定义四类容器,高优先级有序、有序、无序、内部

 

 分类放入四种容器:

 

 

注册BeanPostProcessor,将实现BeanPostProcessor接口的对象放入beanPostProcessors缓存中

 

 

 

 

 

 

注册完PriorityOrdered的实现类后,再处理Ordered的实现类

 

 

注册什么都没有实现的BeanPostProcessor接口实现类,

 

 

最后注册内部的BeanPostProcessor对象

 

 到这里BeanPostProcessor的实例化以及注册工作完成,在beanFactory的beanPostProcessors集合中已经缓存了所有的beanPostProcessor的对象

 

2:BeanPostProcessor的使用

因为这个接口是bean的后置接口,所以需要bean创建并初始化完成,才可以发挥作用,上一步的缓存只是埋好点,以备使用,因为bean的实例化流程我们

还没有分析,这里直接看一下怎么使用的

 

 

我们看一下init方法后的拦截,因为这个时候已经init完成,可以在后置接口中对bean做一下修改的操作

 

 

调用到我们自定义的MyBeanPostProcessor实现类:

 

 

把这个beanDemo对象属性修改一下,修改完,再返回,将这个对象缓存到spring的一级缓存中。

 

 

总结:

  BeanPostProcessor接口主要是对bean对象做一些自定义的操作,修改bean对象的信息,aop代理也是通过这种方式实现的,

在refresh的registryBeanPostProcessor方法中实例化BeanPostProcessor对象,并且注册到beanFactory容器的beanPostProcessors的缓存中,

然后在后续的操作中拦截使用。

 

posted @   程序员三藏  阅读(371)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2016-06-18 2016上半年工作总结
点击右上角即可分享
微信分享提示