spring中的工厂,可以分为创建bean方法工厂和容器中的工厂。两者的区别在于,前者(BeanFactory)为标准的工厂模式,spring需要调用工厂方法去创建bean的实例。而后者(FactoryBean)是spring的特殊bean。

首先介绍,BeanFactory使用工厂方法创建bean,可以分为静态工厂方法和实例工厂方法。

在静态工厂方法中,配置bean时,要包含class和factory-method两个元素。class元素不再指向位bean的实现类,而是指向为静态工厂方法类,factory-method指定静态工厂方法产生bean实例。如果需要向静态工厂方法中传入参数则使用onstructor-arg元素传入。

下面举个例子:

 

//小米手机类
public class MIPhone implements Phone {
    public MIPhone(){
        System.out.println("MIPhone 构造函数被调用");
    }
    private String msg;
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public void call(){
        System.out.println("使用"+msg+"打电话");
    }
}
//apple手机类
public class iPhone implements Phone{
    
    public iPhone(){
        System.out.println("iPhone 构造函数被调用");
    }
    private String msg;
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public void call(){
        System.out.println("使用"+msg+"打电话");
    }

}

 

//静态工厂方法
public class StaticPhoneFactory {
    public StaticPhoneFactory(){
        System.out.println("静态工厂方法被调用");
    }
    public static Phone getPhone(String name){
        if(name.equals("xiaomi")){
            return new MIPhone();
        }else{
            return new iPhone();
        }
        
    }

}
<?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.spring.test.beanfactory.StaticPhoneFactory"
        factory-method="getPhone">
        <constructor-arg value="apple"/>
        <property name="msg" value="iphone5s"/>
    </bean>
    
    <bean id ="xiaomi" class="com.spring.test.beanfactory.StaticPhoneFactory"
        factory-method="getPhone">
        <constructor-arg value="xiaomi"/>
        <property name="msg" value="小米4"/>
    </bean>    

</beans>
//主函数

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class main {
    public static void main(String[] args) {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("beans-factory.xml");
        Phone p1=(MIPhone)ctx.getBean("xiaomi");
        Phone p2=(iPhone)ctx.getBean("apple");
        p1.call();
        p2.call();
    }
}

运行结果为:

image

工厂类并没有被调用,<bean>代码块中的代码可以转化为

//name 为constructor-arg传入的值
phone=com.spring.test.beanfactory.StaticPhoneFactory.getPhone(name);

也就是说,直接调用了类名的静态方法创建对象(上面的构造方法就是在静态方法中调用的),通过静态方法返回bean实例。获得bean实例后与普通方法创建bean实例一样。

 

实例工厂方法无需class属相指向工厂方法,而是用factory-bean指定工厂实例,Spring容器调用工厂bean创建bean实例。

//实例工厂方法
public class phoneFactory {
    public phoneFactory(){
        System.out.println("实例工厂构造函数被调用");
    }
    public Phone getPhone(String name){
        
        if(name.equals("xiaomi")){
            return new MIPhone();
        }else{
            return new iPhone();
        }
        
    }
}
<?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="phonefactory" class="com.spring.test.beanfactory.phoneFactory">
    </bean>
    
    <bean id ="apple" factory-bean="phonefactory"
        factory-method="getPhone">
        <constructor-arg value="apple"/>
        <property name="msg" value="iphone5s"/>
    </bean>
    
    <bean id ="xiaomi" factory-bean="phonefactory"
        factory-method="getPhone">
        <constructor-arg value="xiaomi"/>
        <property name="msg" value="小米4"/>
    </bean>    
</beans>

运行结果为:

image

区别于静态工厂方法,这里工厂类的构造函数被调用,<bean>代码块可以分为两部分

//<bean id="phonefactory" class="com.spring.test.beanfactory.phoneFactory"></bean>
phoneFactory phonefactory=new com.spring.test.beanfactory.phoneFactory ();
//container.put( String,Object);
container.put( phonefactory, phonefactory);
phoneFactory pf=container.get("phonefactory");
xiaomi=pf.getPhone("小米");

首先创建工厂实例放在spring容器中,然后调用该工厂方法创建bean实例。

posted on 2016-03-12 13:15  雷神——托尔  阅读(692)  评论(0)    收藏  举报