Spring 源码梳理(三) 再谈BeanPostProcessor

原创 2016年08月29日 15:23:04

再谈BeanPostProcessor

上篇文章介绍的是BeanPostProcessor的用法,在最后留下了一个问题,对于Spring中的Bean属性'Lazy-init'(延迟加载),当Hook类(BeanPostProcessorApp)或被Hook的类(App)具有这个属性时,会有什么样的表现。

1.接着前面文章的已有的配置,首先我们分别在App和BeanPostProcessorApp上增加构造函数,并且打印一句话:

private App(){
		System.out.println("App.App()");
	}
private BeanPostProcessorApp(){
		System.out.println("BeanPostProcessorApp.BeanPostProcessorApp()");
	}

同时在BeanPostProcessorApp中增加一个after方法(上篇只用到了before):

public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		if(bean instanceof App){
			((App)bean).setSays("After:BeanPostProcessorApp");
		}
		return bean;
	}

然后执行BeanPostProcessorAppTest方法,打印的结果如下:

BeanPostProcessorApp.BeanPostProcessorApp()
App.App()
App.app():After:BeanPostProcessorApp


2.我们调式看一下三条信息分别在什么情况下产生:

1)刚才的第一条信息 “BeanPostProcessorApp.BeanPostProcessorApp() ”是在registerBeanPostProcessors()方法中产生的,也就是说该BeanPostProcessorApp的初始化是在所有BeanPostProcessor注册的时候就进行了。


而这个时候Bean的实例化还没有开始,所以得出这样的结论:

在实现BeanPostProcessor的接口的Bean中增加lazy-init属性是无效的,因为这个Bean在未进行初始化的时候已经被上面的registerBeanPostProcessors初始化了;结合本例,也就是说下面的写法是无效的:


2)再看第二条信息,因为没有设置lazy-init属性,所以在finishBeanFactoryInitialization()方法中就进行了初始化并且创建了实例,如下:


3)最后一条信息则是这样产生的,因为我们在注册BeanPostProcessor的时候已经把我们自己的BeanPostProcessorApp注册了,同时在执行finishBeanFactoryInitialization方法进行Bean的初始化的时候会执行org.springframework.beans.factory.support.AbstractBeanFactory中的getBean方法(上一篇已经介绍了),创建一个实例,进行真正的注入,而我们的

<span style="font-family:SimSun;">App app = (App)applicationContext.getBean("app");</span>

只是得到其中一个引用,最后打印信息。

3.上面分析的结论是,在实现BeanPostProcessor的接口的Bean中增加lazy-init属性是无效的,可以自己实例验证一下,这里就不贴上了;继续分析,如果我们给Bean App增加lazy-init这个属性呢?,如下:


我们可以猜测,因为加上lazy-init属性之后,就不会在Spring的初始化过程中实例化;在org.springframework.beans.factory.support.DefaultListableBeanFactory(上一篇提到过)中我们可以看到,实际上是没有执行org.springframework.beans.factory.support.AbstractBeanFactory的getBean方法:


而这个org.springframework.beans.factory.support.AbstractBeanFactory中的getBean方法实际上是执行了“实例化”+"BeanPostProcessor"这两个功能。

所以猜测1:加载完Spring配置文件不会有第二条信息。

由于我们写的getBean其实就是org.springframework.beans.factory.support.AbstractBeanFactory中的getBean,如下:


所以猜测2:执行完自己的getBean就会进行初始化,并且执行BeanPostProcessor的实现;

验证如下:


如上,证实了猜测1


如上图,在未执行第三个断点says方法之前,says的值已经改变,证实了猜测2.

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

做一个合格的程序猿之浅析Spring IoC源码(五)再谈BeanPostProcessor(2)

上一节,我们已经初步知道了beanPostProcessor这个接口是干什么的了,可以做什么样的事情,并且我们举了一个简单的“Teacher”的例子,但是大家也有点疑问,这个实际意义是什么呢?在项目中...
  • linuu
  • linuu
  • 2016-03-10 15:55
  • 816

做一个合格的程序猿之浅析Spring IoC源码(四)分析BeanPostProcessor(1)

说白了,就是我们可以自定义的去修改spring给我们创建的类,给了我们一个二次修改bean的机会,这种设计思路与spring的“开闭原则”相符合,没有过度分装,举例来说,我们根据beanDefinit...
  • linuu
  • linuu
  • 2016-03-10 13:56
  • 830

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

Mangos源码分析(13):再谈登录服的实现

关于登录服、大区服及游戏世界服的结构之前已做过探讨,这里再把各自的职责和关系列一下。 GateWay/WorldServer GateWay/WodlServer LoginServer ...

再谈spring mvc中的root/child WebApplicationContext

spring mvc只拦截特定路径的url,项目还提供了一个外部的servlet,给别的子系统调用,这个servlet不在spring mvc拦截路径范围内。我们在这个servlet里面不能获取到sp...

Spring之BeanPostProcessor接口

Spring之BeanPostProcessor接口

spring 后置处理器BeanFactoryPostProcessor和BeanPostProcessor的用法和区别

主要区别就是: BeanFactoryPostProcessor可以修改BEAN的配置信息而BeanPostProcessor不能,下面举个例子说明 BEAN类: [java] view plain ...

【Spring学习23】容器扩展点:后置处理器BeanPostProcessor

综述先回顾bean生命周期的这张图,看看BeanPostProcessor调用位置 通过上图看到BeanPostProcessor(Bean后置处理器)两个方法在bean生命周期的位置,即:在Spr...

Spring 的 BeanPostProcessor接口实现

今天学习了一下spring的BeanPostProcessor接口,该接口作用是:如果我们需要在Spring容器完成Bean的实例化,配置和其他的初始化后添加一些自己的逻辑处理,我们就可以定义一个或者...

Spring 的 BeanPostProcessor接口实现

转自http://blog.csdn.net/chensugang/article/details/3423650 今天学习了一下Spring的BeanPostProcessor接口,该接口作用...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)