07--lookup-method和replace-method注入

Spring的方法注入可分為兩種

  • 查找方法注入:用于注入方法返回結(jié)果,也就是說(shuō)能通過(guò)配置方式替換方法返回結(jié)果。即我們通常所說(shuō)的lookup-method注入。
  • 替換方法注入:可以實(shí)現(xiàn)方法主體或返回結(jié)果的替換,即我們通常所說(shuō)的replaced-method注入。
1. lookup-method注入

單例模式的bean只會(huì)被創(chuàng)建一次,IoC容器會(huì)緩存該bean實(shí)例以供下次使用;原型模式的bean每次都會(huì)創(chuàng)建一個(gè)全新的bean,IoC容器不會(huì)緩存該bean的實(shí)例。那么如果現(xiàn)在有一個(gè)單例模式的bean引用了一個(gè)原型模式的bean呢?如果無(wú)特殊處理,則被引用的原型模式的bean也會(huì)被緩存,這就違背了原型模式的初衷,這時(shí)使用lookup-method注入可以解決該問(wèn)題。


  • bean
package com.lyc.cn.v2.day01.method.lookupMethod;

/**
 * @author: LiYanChao
 * @create: 2018-09-05 15:10
 */
public abstract class Car {

    //用于lookup-method注入
    public abstract Taxi createTaxi();

    private Taxi taxi;

    public Taxi getTaxi() {
        return taxi;
    }

    //setter注入
    public void setTaxi(Taxi taxi) {
        this.taxi = taxi;
    }
}

package com.lyc.cn.v2.day01.method.lookupMethod;

/**
 * @author: LiYanChao
 * @create: 2018-09-05 15:10
 */
public class Taxi {
    public void say() {
        System.out.println("I am a Taxi...");
    }
}

  • xml
<!-- ====================lookup-method屬性注入==================== -->
<bean id="car" class="com.lyc.cn.v2.day01.method.lookupMethod.Car">
    <!--注意:下面這句配置和lookup-method注入沒(méi)有關(guān)系,我們只是為了出于演示和說(shuō)明配置該bean-->
    <property name="taxi" ref="taxi"/>
    <!--lookup-method注入-->
    <lookup-method name="createTaxi" bean="taxi"/>
</bean>
<bean id="taxi" class="com.lyc.cn.v2.day01.method.lookupMethod.Taxi" scope="prototype"/>


<!-- ====================replace-method屬性注入==================== -->
<bean id="dogReplaceMethod" class="com.lyc.cn.v2.day01.method.replaceMethod.ReplaceDog"/>
<bean id="originalDogReplaceMethod" class="com.lyc.cn.v2.day01.method.replaceMethod.OriginalDog">
    <replaced-method name="sayHello" replacer="dogReplaceMethod">
        <arg-type match="java.lang.String"></arg-type>
    </replaced-method>
</bean>
  • 測(cè)試
@Test
public void test8() {
    // 測(cè)試lookup-method注入
    Car car1 = xmlBeanFactory.getBean("car", Car.class);
    Car car2 = xmlBeanFactory.getBean("car", Car.class);

    System.out.println("Car:singleton,所以animal1==animal2應(yīng)該為" + (car1 == car2));

    Taxi dog1 = car1.getTaxi();
    Taxi dog2 = car2.getTaxi();
    System.out.println("Taxi:prototype,Car:singleton,未使用lookup-method注入所以dog1==dog2應(yīng)該為" + (dog1 == dog2));

    //注意:這里是通過(guò)createDog()方法獲取
    Taxi taxi3 = car1.createTaxi();
    Taxi taxi4 = car2.createTaxi();
    System.out.println("Taxi:prototype,Car:singleton,使用了lookup-method注入所以dog3==dog4應(yīng)該為" + (taxi3 == taxi4));

}
  • 結(jié)果
========測(cè)試方法開(kāi)始=======

Car:singleton,所以animal1==animal2應(yīng)該為true
Taxi:prototype,Car:singleton,未使用lookup-method注入所以dog1==dog2應(yīng)該為true
Taxi:prototype,Car:singleton,使用了lookup-method注入所以dog3==dog4應(yīng)該為false

========測(cè)試方法結(jié)束=======

  • 分析
    未使用lookup-method注入時(shí),通過(guò)Car的實(shí)例獲取的Taxi實(shí)例是被緩存的(配置文件中Taxi的scope="prototype");而使用了lookup-method注入時(shí),通過(guò)Car的實(shí)例獲取的Taxi實(shí)例則是每次都是新建的,不是被緩存的,這也就達(dá)到了我們的目的。
2. replaced-method注入

主要作用就是替換方法體及其返回值,其實(shí)現(xiàn)也比較簡(jiǎn)單


  • bean
package com.lyc.cn.v2.day01.method.replaceMethod;

/**
 * @author: LiYanChao
 * @create: 2018-09-06 00:01
 */
public class OriginalDog {
    public void sayHello() {
        System.out.println("Hello,I am a black dog...");
    }

    public void sayHello(String name) {
        System.out.println("Hello,I am a black dog, my name is " + name);
    }
}

package com.lyc.cn.v2.day01.method.replaceMethod;

import org.springframework.beans.factory.support.MethodReplacer;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author: LiYanChao
 * @create: 2018-09-06 00:02
 */
public class ReplaceDog implements MethodReplacer {
    @Override
    public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
        System.out.println("Hello, I am a white dog...");

        Arrays.stream(args).forEach(str -> System.out.println("參數(shù):" + str));
        return obj;
    }
}

replace-method注入需實(shí)現(xiàn)MethodReplacer接口,并重寫(xiě)reimplement方法。

  • xml
<!-- ====================replace-method屬性注入==================== -->
<bean id="dogReplaceMethod" class="com.lyc.cn.v2.day01.method.replaceMethod.ReplaceDog"/>
<bean id="originalDogReplaceMethod" class="com.lyc.cn.v2.day01.method.replaceMethod.OriginalDog">
    <replaced-method name="sayHello" replacer="dogReplaceMethod">
        <arg-type match="java.lang.String"></arg-type>
    </replaced-method>
</bean>
  • 測(cè)試
@Test
public void test9() {
    //測(cè)試replace-method注入
    OriginalDog originalDog = xmlBeanFactory.getBean("originalDogReplaceMethod", OriginalDog.class);
    originalDog.sayHello("輸出結(jié)果已經(jīng)被替換了。。。");
}
  • 結(jié)果
========測(cè)試方法開(kāi)始=======

Hello, I am a white dog...
參數(shù):輸出結(jié)果已經(jīng)被替換了。。。

========測(cè)試方法結(jié)束=======
  • 分析
    OriginalDog類的sayHello方法輸出的是Hello,I am a black dog, my name is xxx,但是通過(guò)replace-method注入,成功的將其替換成reimplement方法。

本節(jié)的內(nèi)容基于配置,只要了解如何配置,就可以正常使用了,不在做過(guò)多的分析。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.1 spring IoC容器和beans的簡(jiǎn)介 Spring 框架的最核心基礎(chǔ)的功能是IoC(控制反轉(zhuǎn))容器,...
    simoscode閱讀 6,846評(píng)論 2 22
  • 1.1 Spring IoC容器和bean簡(jiǎn)介 本章介紹了Spring Framework實(shí)現(xiàn)的控制反轉(zhuǎn)(IoC)...
    起名真是難閱讀 2,670評(píng)論 0 8
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,535評(píng)論 19 139
  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan閱讀 4,488評(píng)論 2 7
  • 學(xué)生時(shí)讀過(guò)的現(xiàn)代詩(shī)中,我唯一只記得是臧克家先生的幾句話:有的人活著,他已經(jīng)死了。有的人死了,他還活著。當(dāng)時(shí)年少,盡...
    老少女簌簌閱讀 539評(píng)論 0 1

友情鏈接更多精彩內(nèi)容