协调作用域不同的Bean

当两个singleton作用域的Bean存在依赖关系,或者prototype作用域依赖singleton作用域时,使用Spring提供的依赖注入管理即可。但如果作用域为singleton依赖作用域prototype的Bean,singleton作用域在初始化阶段会设置好依赖关系且仅一次,在初始化singleton的bean时,会先创建被依赖的prototype bean,后再初始化singleton的bean,再将prototype的bean注入到singleton中。这样子的话,会导致每次 singleton bean 去访问prototype bean 时,每次都是得到最开始的那个prototype bean。这样子的话,会违背了最开始的初衷:本来应该表现出prototype 行为的bean,却表现出了singleton行为。(每次得到的都是同一个Bean)

解决方法:利用方法注入。采用lookup方法注入。下面举个例子来介绍下。

场景期望:有一个Bean A为singleton作用域依赖于作用域为prototype的Bean,每次Bean A去调用Bean B时,期望 能得到的 Bean B 是全新的,即作用域为prototype。

因渣渣程序猿近来中了王者农药的毒太深,所以 举个 我最爱的本命英雄张良来解释下。

张良 一个类 (Bean)-------------------->依赖                  (皮肤)     天堂福音(Bean)

期望每次张良类调用皮肤天堂福音都是新生成的(我不知道这样合理不,在此是为了说明这个例子而已)

首先,定义一个皮肤接口


协调作用域不同的Bean_第1张图片
皮肤接口

接下来新建个天堂福音的类去实现皮肤接口


协调作用域不同的Bean_第2张图片

通过Spring配置,注入“法师”,“10”个法术值,“天堂福音”名称实例化天堂福音的类。

协调作用域不同的Bean_第3张图片
皮肤的XML配置

新建个张良类,在类中新建 天堂福音 类的属性,按一般来说,就是通过直接setter注入就能完成两个Bean间的依赖关系,但是这样子的话,会导致天堂福音类表面是prototype作用域,却表现出singleton作用域的行为,与我们期望的不符合。

所以,我们通过lookup注入的方法,首先,将调用者 张良 类 定义为 抽象类,,并定义一个抽象方法,该方法用以得到被依赖的Bean.


协调作用域不同的Bean_第4张图片

接下来 需要去配置Spring容器的XML文件,lookup-method 有两个属性,name:指定需要让Spring实现的方法。  bean:指定Spring实现该方法的返回值。

看到这里相信大家和我一样也是一脸蒙了,刚开始我也是看不懂,这个抽象方法public abstract  天堂福音 getSkin() 是怎么实现的?莫名其妙就可以调用了,都不用写实现方法体。原来,Spring会负责实现getSkin()的方法。

这个方法是Spring自动实现的,不需要我们自己打。

public 天堂福音 getSkin()

{

    //获取Spring 容器 ctx

     .......

  ////

//  "天堂福音"是上面的lookup-method 的属性Bean指定的。

return ctx.getBean("天堂福音");

}


协调作用域不同的Bean_第5张图片


协调作用域不同的Bean_第6张图片
结果说明每次都是生成新的皮肤

总结:使用lookup注入后,系统每次调用getSkin()方法后得到的都是一个全新的天堂福音实例。这样能够保证,在singleton作用域下调用prototype作用域时得到的也能够表现出prototype行为,而不是singleton。

你可能感兴趣的:(协调作用域不同的Bean)