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(); } }
运行结果为:
工厂类并没有被调用,<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>
运行结果为:
区别于静态工厂方法,这里工厂类的构造函数被调用,<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实例。


浙公网安备 33010602011771号