工厂方法模式和FactoryBean

  • Post author:
  • Post category:其他


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>



版权声明:本文为qq_45923275原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。