问题
无状态Bean的作用域一般可以配置为singleton(单例模式),如果我们往singleton的Pilot类中注入prototype的Plane类,并希望每次调用Pilot的getPlane()方法都能返回一个新的plane Bean ,该怎么办呢?
如果我们使用传统的注入方式将无法实现这样的需求, 因为Singleton的Bean注入关联Bean的动作仅有一次,虽然 plane Bean的作用范围是prototype,但是 Pilot通过getPlane()方法返回的对象还是最开始注入的那个plane Bean .
如果希望每次每次调用getPlane()方法都返回一个新的plane Bean, 一种可选的方法是让Pilot类实现BeanFactoryAware接口,且能够访问容器的引用。
但是上面的方法依赖SPring框架接口,十分不友好。 有没有其他办法呢?
lookup方法注入
Spring IoC容器拥有复写Bean方法的能力,主要源于CGLib类包。
CGlib可以找运行期间动态操作class字节码,为Bean动态创建子类或者实现类。
<?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">
<!-- prototype类型的Bean -->
<bean id="plane" class="com.xgj.ioc.lookup.Plane" scope="prototype" />
<!-- 实施方法注入 -->
<bean id="magicPilot" class="com.xgj.ioc.lookup.MagicPilot">
<lookup-method name="getPlane" bean="plane" />
</bean>
</beans>
通过lookup-method
元素标签为MagicPlane的getPlane方法提供动态实现,返回prototype类型的Plane bean , 这样Spring将在运行期为MagicPlane接口提供动态实现。
小结
lookup 方法的使用场景: 一般在希望通过一个singleton Bean获取一个prototype Bean时使用
—————————————————————————
方法替换MethodReplacer接口
使用某个Bean的方法替换另外一个Bean的方法。
必须实现 org.springframework.beans.factory.support.MethodReplacer 接口,重写reimplement方法。
<?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">
<!-- 使用pilotTwo的MethodReplacer接口方法替换该Bean的getPlane方法 -->
<bean id="pilotOne" class="com.xgj.ioc.methodReplace.PilotOne">
<replaced-method name="getPlane" replacer="pilotTwo"/>
</bean>
<bean id="pilotTwo" class="com.xgj.ioc.methodReplace.PilotTwo"/>
</beans>
小结
用于替换他人的Bean必须实现MethodReplacer接口,Spring利用该接口的方法去替换目标Bean的方法。