首页 > 编程语言 > 详细

Spring lookup-method注入和replace-method注入

时间:2020-04-15 17:05:23      阅读:142      评论:0      收藏:0      [点我收藏+]

方法注入可分为两种

  • 查找方法注入:用于注入方法返回结果,也就是说能通过配置方式替换方法返回结果。即我们通常所说的lookup-method注入
  • 替换方法注入:可以实现方法主体或返回结果的替换,即我们通常所说的replaced-method注入

1. lookup-method注入


 

  在Spring容器中,单例模式的bean只会被创建一次,然后容器会缓存该单例bean的实例,等到第二次获取时,可以直接返回该bean的实例,而无需重新创建;原型模式的bean则是每次都会创建一个全新的bean,Spring容器并不会缓存该bean的实例以供下次使用。那么如果现在有一个单例模式的bean引用了一个原型模式的bean呢?我们不希望被引用的原型模式bean被缓存,那么这个时候就需要用到lookup-method注入。

  • 新建Dog类和Animal抽象类
package com.lyc.cn.day05.lookupMethod;

/**
 * @author: LiYanChao
 * @create: 2018-09-05 15:10
 */
public class Dog {
    public void say() {
        System.out.println("I am a Dog...");
    }
}
package com.lyc.cn.day05.lookupMethod;

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

    //用于lookup-method注入
    public abstract Dog createDog();

    private Dog dog;

    public Dog getDog() {
        return dog;
    }

    //setter注入
    public void setDog(Dog dog) {
        this.dog = dog;
    }
}
  • 新建day05.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
        
    <!-- ====================lookup-method属性注入begin==================== -->
    <bean id="animal" class="com.lyc.cn.day05.lookupMethod.Animal">
        <!--注意:下面这句配置和lookup-method注入没有关系,我们只是为了出于演示和说明配置该bean-->
        <property name="dog" ref="dog"/>
        <!--lookup-method注入-->
        <lookup-method name="createDog" bean="dog"/>
    </bean>
    <bean id="dog" class="com.lyc.cn.day05.lookupMethod.Dog" scope="prototype"/>
    <!-- ====================lookup-method属性注入end==================== -->
    
</beans>
  • 新建MyTest,添加测试用例
package com.lyc.cn.day05;

import com.lyc.cn.day05.lookupMethod.Animal;
import com.lyc.cn.day05.lookupMethod.Dog;
import com.lyc.cn.day05.replaceMethod.OriginalDog;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

/**
 * @author: LiYanChao
 * @create: 2018-09-08 01:01
 */
public class MyTest {
    private XmlBeanFactory xmlBeanFactory;

    @Before
    public void initXmlBeanFactory() {
        System.out.println("========测试方法开始=======\n");
        xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("day05.xml"));
    }

    @After
    public void after() {
        System.out.println("\n========测试方法结束=======");
    }

    @Test
    public void testLookUp() {
        Animal animal1 = xmlBeanFactory.getBean("animal", Animal.class);
        Animal animal2 = xmlBeanFactory.getBean("animal", Animal.class);

        System.out.println("Animal:singleton,所以animal1==animal2应该为" + (animal1 == animal2));

        Dog dog1 = animal1.getDog();
        Dog dog2 = animal1.getDog();
        System.out.println("Dog:prototype,Animal:singleton,未使用lookup-method注入所以dog1==dog2应该为" + (dog1 == dog2));

        //注意:这里是通过createDog()方法获取
        Dog dog3 = animal1.createDog();
        Dog dog4 = animal1.createDog();
        System.out.println("Dog:prototype,Animal:singleton,使用了lookup-method注入所以dog3==dog4应该为" + (dog3 == dog4));

    }
}
  • 运行测试用例
========测试方法开始=======

Animal:singleton,所以animal1==animal2应该为true
Dog:prototype,Animal:singleton,未使用lookup-method注入所以dog1==dog2应该为true
Dog:prototype,Animal:singleton,使用了lookup-method注入所以dog3==dog4应该为false

========测试方法结束=======

从运行结果可以看到

  • Animal的作用域是singleton,所以虽然执行了两次getBean()方法,但是返回的是同一个Animal实例。
  • Dog的作用域虽然是prototype,但是通过Setter方法注入的Dog返回的仍然是同一个对象,明显不符合prototype的概念。
  • 通过lookup-method注入的Dog,每次返回的都是不同的对象,符合prototype的概念。

2. replaced-method注入


主要作用就是替换方法体及其返回值,其实现也比较简单

  • 新建OriginalDog和ReplaceDog(需实现MethodReplacer接口)
package com.lyc.cn.day05.replaceMethod;

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

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

import java.lang.reflect.Method;

/**
 * @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...");
        return obj;
    }
}
  • 修改day05.xml添加bean配置
<!-- ====================replace-method属性注入begin==================== -->
<bean id="replaceDog" class="com.lyc.cn.day05.replaceMethod.ReplaceDog"/>
<bean id="originalDog" class="com.lyc.cn.day05.replaceMethod.OriginalDog">
    <replaced-method name="sayHello" replacer="replaceDog"/>
</bean>
<!-- ====================replace-method属性注入end==================== -->
  • 修改MyTest类添加测试用例
/**
 * 测试replace-method注入
 */
@Test
public void testReplace() {
    OriginalDog originalDog = xmlBeanFactory.getBean("originalDog", OriginalDog.class);
    originalDog.sayHello();
}
  • 运行测试用例
========测试方法开始=======

Hello, I am a white dog...

========测试方法结束=======

查看结果,原本OriginalDog中的sayHell()输出已经被替换掉了。

关于Spring依赖注入的三种方式到这里就全部讲完了,lookup-method和replace-method在实际开发中并不多见,但是应该有所了解,其底层涉及到的动态代理等机制,还是值得我们去深入了解的,具体的实现我们会在接下来的章节中进行分析。
————————————————
原文链接:https://blog.csdn.net/lyc_liyanchao/java/article/details/82432993

Spring lookup-method注入和replace-method注入

原文:https://www.cnblogs.com/w2116o2115/p/12706232.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!