Spring - lookup-method方式实现依赖注入

本文内容纲要:Spring - lookup-method方式实现依赖注入

引言

假设一个单例模式的bean A需要引用另外一个非单例模式的bean B,为了在我们每次引用的时候都能拿到最新的bean B,我们可以让bean A通过实现ApplicationContextWare来感知applicationContext(即可以获得容器上下文),从而能在运行时通过ApplicationContext.getBean(String beanName)的方法来获取最新的bean B。但是如果用ApplicationContextAware接口,就让我们与Spring代码耦合了,违背了反转控制原则(IoC,即bean完全由Spring容器管理,我们自己的代码只需要用bean就可以了)。

所以Spring为我们提供了方法注入的方式来实现以上的场景。方法注入方式主要是通过标签。

实例

下面我们用一个例子来说明lookup-method的用法。

假设有一个果盘,果盘里放了一些水果,比如苹果,香蕉等,我们希望我们每次在果盘里拿到的都是最新鲜的水果。

java代码:

// 定义一个水果类

public class Fruit {

public Fruit() {

System.out.println("I got Fruit");

}

}

// 苹果

public class Apple extends Fruit {

public Apple() {

System.out.println("I got a fresh apple");

}

}

// 香蕉

public class Bananer extends Fruit {

public Bananer () {

System.out.println("I got a fresh bananer");

}

}

// 水果盘,可以拿到水果

public abstract class FruitPlate{

// 抽象方法获取新鲜水果

protected abstract Fruit getFruit();

}

spring配置:

<!-- 这是2个非单例模式的bean -->

<bean id="apple" class="cn.com.willchen.test.di.Apple" scope="prototype"/>

<bean id="bananer" class="cn.com.willchen.test.di.Bananer " scope="prototype"/>

<bean id="fruitPlate1" class="cn.com.willchen.test.di.FruitPlate">

<lookup-method name="getFruit" bean="apple"/>

</bean>

<bean id="fruitPlate2" class="cn.com.willchen.test.di.FruitPlate">

<lookup-method name="getFruit" bean="bananer"/>

</bean>

测试代码:

public static void main(String[] args) {

ApplicationContext app = new ClassPathXmlApplicationContext("classpath:resource/applicationContext.xml");

FruitPlate fp1= (FruitPlate)app.getBean("fruitPlate1");

FruitPlate fp2 = (FruitPlate)app.getBean("fruitPlate2");

fp1.getFruit();

fp2.getFruit();

}

测试结果:

I got Fruit

I got a fresh apple

I got Fruit

I got a fresh bananer

示例说明:

从上面例子我们可以看到,在代码中,我们没有用到Spring的任何类和接口,实现了与Spring代码的耦合。

其中,最为核心的部分就是lookup-method的配置和FruitPlate.getFruit()方法。上面代码中,我们可以看到getFruit()方法是个抽象方法,我们并没有实现它啊,那它是怎么拿到水果的呢。这里的奥妙就是Srping应用了CGLIB(动态代理)类库。Spring在初始化容器的时候对配置的bean做了特殊处理,Spring会对bean指定的class做动态代理,代理标签中name属性所指定的方法,返回bean属性指定的bean实例对象。每次我们调用fruitPlate1或者fruitPlate2这2个bean的getFruit()方法时,其实是调用了CGLIB生成的动态代理类的方法。关于CGLIB大家可自行在网上查阅。

lookup-method实现方式说明:

<bean class="beanClass">

<lookup-method name="method" bean="non-singleton-bean"/>

</bean>

method是beanClass中的一个方法,beanClass和method是不是抽象都无所谓,不会影响CGLIB的动态代理,根据项目实际需求去定义。non-singleton-bean指的是lookup-method中bean属性指向的必须是一个非单例模式的bean,当然如果不是也不会报错,只是每次得到的都是相同引用的bean(同一个实例),这样用lookup-method就没有意义了。

另外对于method在代码中的签名有下面的标准:

<public|protected> [abstract] theMethodName(no-arguments);

public|protected要求方法必须是可以被子类重写和调用的;

abstract可选,如果是抽象方法,CGLIB的动态代理类就会实现这个方法,如果不是抽象方法,就会覆盖这个方法,所以没什么影响;

return-type就是non-singleton-bean的类型咯,当然可以是它的父类或者接口。

no-arguments不允许有参数。

本文内容总结:Spring - lookup-method方式实现依赖注入

原文链接:https://www.cnblogs.com/ViviChan/p/4981619.html

以上是 Spring - lookup-method方式实现依赖注入 的全部内容, 来源链接: utcz.com/z/362620.html

回到顶部