IOC容器支持工厂方法模式
降低接口和实现类的耦合可以通过工厂方法模式,Spring的IOC容器提供了通过工厂方法模式创建实例的支持。
静态工厂方法
当工厂类获取实例的方法为静态时,可以在将工厂注册bean的Factory-method属性值设置为静态方法名字。
<bean id="factoryBean" class="FactoryBean" factory-method="getInstance"/>
public class FactoryBean {
public static IOC_User getInstance(){
return new IOC_User();
}
}
如果获取实例方法有参数,可以通过设置工厂bean的<constructor-arg>来实现(一般静态工厂方法实现类没有显式的构造方法)
非静态工厂方法
public class FactoryBean {
public IOC_User getInstance(String a){
return new IOC_User();
}
}
<bean id="factoryBean" class="FactoryBean" />
<bean id="factory" factory-bean="factoryBean" factory-method="getInstance">
<constructor-arg value="msf"></constructor-arg>
</bean>
需要User实例时候ref指定为factory即可
FactoryBean
不要混淆FactoryBean和BeanFactory,前者是一个bean,Factory是定语用来描述这个bean的功能,后者则是Spring提供的基本IOC容器。
实现了Spring提供的FactoryBean接口的工厂类具有特殊的性质。
将工厂类注册到IOC容器中时,通过正常的id引用返回的将会是该工厂生产的实例对象,如果硬要该工厂本身可以在之前加一个&符号。
方法注入
对于某个bean中的非final无参方法,在配置该bean时可以将需要返回的bean注入
<bean id="factoryBean" class="FactoryBean" >
<lookup-method bean="user" name="getObject"/>
</bean>
public IOC_User getObject() {
return null;
}
在Spring揭秘这本书中是这样引入这个功能的
当IOC容器初始化完成的时候,所有的bean横向之间的依赖关系就已经注入完成,当调用一个bean中getXXX的方法返回另外一个bean时候,即便设置了被返回bean的生命周期为prototype,依旧会每次返回同一个bean。
为了解决这个问题采用了上述方案注入方法的返回值。
方法替换
利用IOC容器可以将bean方法的逻辑与返回值整体替换,实现MethodReplacer接口即可。
与子类继承不同,这种替换可以改变返回值类型和参数类型
import org.springframework.beans.factory.support.MethodReplacer;
import java.lang.reflect.Method;
public class FactoryBean{
public void getObject() {
System.out.println("原方法执行");
}
}
class replace implements MethodReplacer {
@Override
public Object reimplement(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("被替换方法执行");
return null;
}
}
<bean id="factoryBean" class="FactoryBean" >
<replaced-method name="getObject" replacer="replace"></replaced-method>
</bean>
<bean id="replace" class="replace"></bean>