package com.mashibing.methodOverrides.lookup;
public class Apple extends Fruit {
private Banana banana;
public Apple() {
System.out.println("I got a fresh apple");
}
public Banana getBanana() {
return banana;
}
public void setBanana(Banana banana) {
this.banana = banana;
}
}
package com.mashibing.methodOverrides.lookup;
public class Banana extends Fruit {
public Banana() {
System.out.println("I got a fresh bananer");
}
}
package com.mashibing.methodOverrides.lookup;
public class Fruit {
public Fruit() {
System.out.println("I got Fruit");
}
}
package com.mashibing.methodOverrides.lookup;
public abstract class FruitPlate{
// 抽象方法获取新鲜水果
public abstract Fruit getFruit();
}
<?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">
<bean id="apple" class="com.mashibing.methodOverrides.lookup.Apple" >
<property name="banana" ref="banana"></property>
</bean>
<bean id="banana" class="com.mashibing.methodOverrides.lookup.Banana" scope="prototype">
</bean>
<bean id="fruitplate1" class="com.mashibing.methodOverrides.lookup.FruitPlate">
<lookup-method name="getFruit" bean="apple"></lookup-method>
</bean>
<bean id="fruitplate2" class="com.mashibing.methodOverrides.lookup.FruitPlate">
<lookup-method name="getFruit" bean="banana"></lookup-method>
</bean>
</beans>
package com.mashibing;
import com.mashibing.methodOverrides.lookup.Apple;
import com.mashibing.methodOverrides.lookup.FruitPlate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* spring中默认的对象都是单例的,spring会在一级缓存中持有该对象,方便下次直接获取,
* 那么如果是原型作用域的话,会创建一个新的对象
* 如果想在一个单例模式的bean下引用一个原型模式的bean,怎么办?
* 在此时就需要引用lookup-method标签来解决此问题
*
* 通过拦截器的方式每次需要的时候都去创建最新的对象,而不会把原型对象缓存起来,
*
*/
public class TestMethodOverride {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("methodOverride.xml");
Apple bean = ac.getBean(Apple.class);
System.out.println(bean.getBanana());
Apple bean2 = ac.getBean(Apple.class);
System.out.println(bean2.getBanana());
// FruitPlate fruitplate1 = (FruitPlate) ac.getBean("fruitplate1");
// fruitplate1.getFruit();
// FruitPlate fruitplate2 = (FruitPlate) ac.getBean("fruitplate1");
// fruitplate2.getFruit();
// FruitPlate fruitplate2 = (FruitPlate) ac.getBean("fruitplate2");
// fruitplate2.getFruit();
}
}
如果Apple是单例,Banana是原型,即,单例引用原型。那么,如果不改动标签的话(不使用look-up标签),则Apple填充属性时,直接创建一个Banana,知道Apple完成后,放入ioc容器中后,就不会变化了,所以,此时无论Apple调用多少次Banana,都只会返回同一个Banana,因为Apple里一直都是同一个Banana。
而如果使用look-up,则spring完成后,存放到ioc容器的Apple是一个cglib代理对象,每次getBanana时,会执行cglibinception,创建一个新的Banana对象。
附使用look-up标签代码
ApplicationContext ac = new ClassPathXmlApplicationContext("methodOverride.xml");
Apple bean = ac.getBean(Apple.class);
System.out.println(bean.getBanana());
Apple bean2 = ac.getBean(Apple.class);
System.out.println(bean2.getBanana());
<?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">
<bean id="apple" class="com.mashibing.methodOverrides.lookup.Apple" >
<property name="banana" ref="banana"></property>
<lookup-method name="getBanana" bean="banana"></lookup-method>
</bean>
<bean id="banana" class="com.mashibing.methodOverrides.lookup.Banana" scope="prototype">
</bean>
<bean id="fruitplate1" class="com.mashibing.methodOverrides.lookup.FruitPlate">
<lookup-method name="getFruit" bean="apple"></lookup-method>
</bean>
<bean id="fruitplate2" class="com.mashibing.methodOverrides.lookup.FruitPlate">
<lookup-method name="getFruit" bean="banana"></lookup-method>
</bean>
</beans>