答读者问:BeanFactoryPostProcessor似乎失效了?

有小伙伴在学习 Spring 源码视频的时候,看了松哥讲的 BeanFactoryPostProcessor 的用法之后,提出了这样一个问题:

为崇义等地区用户提供了全套网页设计制作服务,及崇义网站建设行业解决方案。主营业务为做网站、网站制作、崇义网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

图片

图片

我来跟大家补充一下这个问题的上下文:

我讲了 BeanFactoryPostProcessor,分析了其原理,也讲了具体的使用场景,一个典型的使用场景是我们在 XML 中定义 Bean 的时候,如果 Bean 的属性是使用了 properties 文件占位符如 ${db.username} 这种,那么在 BeanFactoryPostProcessor 阶段,就会对这个占位符进行处理,将其替换成真正的 value。然后我还顺手给大家举了一个例子,我在 XML 文件中定义 Bean 的时候,给 Bean 的某一个属性设置 value 为 ^username,然后在 BeanFactoryPostProcessor 中,我将 ^username 改为某一个字符串。

小伙伴看了松哥讲的内容之后,也照着写了一个,就是上面图片中的代码,不同的是,他是将 XML 配置改为了 Java 代码配置,结果发现属性 hok 并未变为 NB,因此有了上述问题。

我觉得这个问题问的很好,给了小伙伴们一个从其他方面理解 Spring 的机会,这也是我前面一直强调的,这次的 Spring 视频需要各位小伙伴一起发力,大家有关于 Spring 的任何问题都可以提,我负责通过源码来回答你。

问题分析

这个问题的分析,得先从 BeanDefinition 开始。在讲 BeanFactoryPostProcessor 之前,松哥已经和小伙伴们分析过 BeanDefinition 了,无论我们是通过 Java 代码还是通过 XML 文件定义的 Bean 对象,在解析称为 Bean 对象之前,得先解析成为 BeanDefinition,BeanDefinition 则有不同的分类,对于 XML 文件定义的 Bean,最终解析为 GenericBeanDefinition,而通过 @Bean 注解定义的 Bean 则解析为 ConfigurationClassBeanDefinition。

但是这两个的处理原理显然是有差异的。

对于 XML 定义的 Bean 来说,很明显 XML 中的所有属性都要先解析到 BeanDefinition 中,包括我们在 XML 中配置的 Bean 的各种属性,这一步是在 Spring 容器 refresh 方法中构建 BeanFactory 的时候完成的(obtainFreshBeanFactory 方法),这一步完成之后,在后面的步骤会去执行容器中所有的 BeanFactoryPostProcessor(invokeBeanFactoryPostProcessors),此时就会把前面解析出来的 BeanDefinition 中带有占位符的属性给替换过来,最后在 refresh 方法中执行 finishBeanFactoryInitialization 方法完成 Bean 的初始化。

按照上面这一套流程顺序,占位符被解析成为正常字符串没什么问题。

但是,如果是 @Bean 注解配置的 Bean,则会有所差异。

首先,@Bean 注解所标记的方法要被解析为一个 ConfigurationClassBeanDefinition,这个过程本身是通过 ConfigurationClassPostProcessor 来完成的,而 ConfigurationClassPostProcessor 本质上其实就是一个 BeanFactoryPostProcessor,换言之,@Bean 注解标记的方法是在 BeanFactoryPostProcessor 中被解析为 ConfigurationClassBeanDefinition 的。ConfigurationClassBeanDefinition 这个 BeanDefinition 主要用来记录 @Bean 注解所标记的方法所属的对象、方法的名称、方法对象、方法参数、注解的参数等等信息,把这些信息记录下来,将来在初始化 Bean 的时候,通过反射执行目标方法就可以了,即方法里边的内容是什么,ConfigurationClassBeanDefinition 其实并不关心。

最后则是和 XML 一样,在 finishBeanFactoryInitialization 方法中完成 Bean 的初始化。

经过上面分析,小伙伴们可以看到,通过 @Bean 注解定义的 Bean,我们为属性赋值是在方法内部完成的,这些方法内部的逻辑其实并未被解析到 BeanDefinition 中,显然也没有必要把方法内部的逻辑解析到 BeanDefinition 上去,因此,通过 @Bean 注解定义的 Bean,如果属性中使用了占位符,是无法通过 BeanFactoryPostProcessor 自动解析的。

好啦,现在小伙伴提出的问题大家伙都明白了吧?

本文名称:答读者问:BeanFactoryPostProcessor似乎失效了?
文章出自:http://www.gawzjz.com/qtweb2/news6/8606.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联