Spring lookup-method注入和replace-method注入
方法注入可分为两种
- 查找方法注入:用于注入方法返回结果,也就是说能通过配置方式替换方法返回结果。即我们通常所说的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

浙公网安备 33010602011771号