Spring 源码六

图1

图3

图4

图5

 

图6

图7

添加了BeanPostProcessor()

图8

图9

判断是否代理过,如果实现了EnHancedConfiguration这个接口证明被代理过,直接返回。

图10

图11

图12

图13

代理后的对象有$beanFactory对象的属性。

图14

图15

得到beanFactory工厂。现在的问题是要理解原始类和我们的cgilb产生的类有什么关系呢,图16为原始类。问题来了,那我调用Appconfig appconfig = getBean(); 获取的appconfig应该是图17xxxx,调用的方法应该是xxxx.userService(); 这个方法里面的行为是否发生了改变呢或者是有什么关联呢,这个是要研究的问题。

beanMethod是调用的方法。判断执行的方法和调用的方法是不是同一个方法,如果是则证明是第一次调用采用new的方式,如果不是采用去factory中getBean()中获取。那到底什么是执行方法,什么是调用方法呢。图22有解析。如果是的话是new吗,看spring 的源码不是new 而是直接调用父类的方法。invokeSuper()方法。如果不是则只需resolveBeanReference()方法。来 $$ beanFactory.getBean()图23.

图16

 15行应该去掉static。

图17

假设cglib生产的类是这样的。

图18

为获取真正的cglib代理类。

图19

this.CGLIB$CALLBACK_0对应的是图20  LubanMethodInterceptor类。如果var10000不等于null 调用LubanMethodInterceptor 的intercept方法。

 

图20  LubanMethodInterceptor

method为当期调用的方法也就是执行方法,methodProxy为代理方法也就是调用方法。举例说明,当第一次调用时,当期的method 的为 query()方法,methodProxy为query()方法。当第二次调用的时候method为query()方法,methodProxy为query2()方法。图22。

图21

currentlyInvoked获取的时调用方法,method为执行方法。比较两个方法的方法名称是否相当,参数列表是否相等,如果相等证明是第一次采用new的方式,如果不相等证明不是第一次采用获取的方式。

图22

query()方法没有嵌套方法时 即为调用方法又为执行方法。 query2()方法有嵌套方法这个时候,query2为调用方法,query()为执行方法。

图23

最重要的是beanFactory.getBean()整个方法,获取bean返回。

这个beanFactroy.registerDependentBean()方法设置了bd.

其他的都不重要。

图24

图25

延迟加载,就是在@configuration注解处理完之后才处理这个类。

图26

 

图27

总结:

 

1.BeanPostProcessor spring的后置处理器,作用是插手bean的实例化过程,实例化之后,在bean没有放在容器singLetonObjects<k,v>之前。图28  ,经典场景@PolstConstruct,aop   

BeanPostProcessor 是  bean 后置处理器,是spring提供的一个扩展点,我们程序员只需要去实现BeanPostProcessor的一个接口,就能插手bean的一个实例化过程。咋么插手呢,就是在bean放在singLetonObjects之前 做一个插手。对bean进行一些改变。

  经典场景,bean的生命周期回调 ,那是哪个类实现这个BeanPostProcessor类,完成回调呢,是这个图29   是这个类CommonAnnotationBeanPostProcessor

2.BeanFactroyPostProcessor  图30  spring 的核心类ConfigrationClssPostProcessor  ,的postProcessBeanFactory() 这个方法 ,来判断是否加了@Configration注解如果加说明是一个全注解(full).如果是全注解这个方法会使用cglib生成代理类,如果没有加还是原来的类。

3BeanDefinitionRegistryPostProcessor 图31  spring 的核心类ConfigrationClssPostProcessor  的postProcessBeanDefinitionRegistry() 这个方法来完成扫描,三种import的扫描,bean的扫描,判断类的注解是不是一个全注解。 先遍历BeanDefinitionRegistryPostProcessor(spirng内部的,和自定义的) ,那么怎么操作算是自定义的,手动添加一个add BeanPostProcessor();图32

4.importSelector 图27  通过这个selectImports ()的方法返回一个全类名的字符串数组,把他变成bd,动态添加bd,注意这个bd是死的,为什么说这个bd是死的呢,因为从class到bd这个过程是spring来操作,我们程序员没有办法干预。class是什么spring就会操作成什么样的bd放在容器中。 就相当于说spring告诉我们,你返回一个全类名我来帮你转化成bd.。当我们不需要动态的改变bd的时候我们选择用importSelector。如果我们需要动态的改变bd我们就需要用importBeanDefinitionRegistrar了。

5.importBeanDefinitionRegistrar 图26  比ImportSelector的类多了BeanDefinitionRegistry ,所以可以动态的改变bd.  通过registry来注册扫描器,然后通过扫描器把改变的bd添加到beanDefinitionMap中。还可以通过图37改变UserMapper的类型。

图28

图29

图30

图31

图32

图33

图34

图35

图36-0

图36

图37

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值