持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情
前言
我们之前学习的IoC实际上就是一个典型的工厂方法,这篇文章带你了解Spring如何通过工厂方法来创建bean。
Spring工厂方法
什么是工厂方法
前面说过IoC就是一个典型的工厂方法。那我们思考一下,IoC是怎样工作的呢,为什么IoC被称为典型的工厂方法?
我们联系实际生活中的工厂,工厂的作用是生产产品,当我们需要产品的时候,就可以向工厂下订单,然后工厂就会交付产品。Spring的工厂也是一样的,只不过Spring工厂中的产品就是bean,而当我们需要bean时就从工厂方法中去取。这就是Spring的工厂方法的一个概念。
而Spring的工厂方法又分为静态工厂方法和实例工厂方法。
静态工厂
概念
静态工厂的定义就是我们不需要去实例化工厂,可以直接调用工厂中的静态方法从而获取对象。
代码示例
1.我们先创建一个Phone的类。
package com.xyj;
import lombok.Data;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Phone {
private int id;
private String name;
private String brand;
}
2.再创建一个静态工厂的类,在工厂中,我们需要有个容器存储生产好的手机,然后提供个方法供外部调用。
package factory;
import com.xyj.Phone;
import java.util.HashMap;
import java.util.Map;
public class StaticFactory {
private static Map<Integer, Phone> phoneMap;
static {
phoneMap = new HashMap<Integer,Phone>();
phoneMap.put(1,new Phone(1,"小米","小米10"));
phoneMap.put(2,new Phone(2,"华为","华为P50"));
phoneMap.put(3,new Phone(3,"荣耀","荣耀30"));
}
public static Phone getPhone(int id){
return phoneMap.get(id);
}
}
static方法是为了确保静态工厂类一加载就创建。
3.在IoC配置文件中配置静态工厂
<bean id="phone"
class="factory.StaticFactory" factory-method="getPhone">
<constructor-arg value="1"></constructor-arg>
</bean>
factory-method:静态工厂类的静态方法;
4.获取phone的对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-factory.xml");
Phone phone = (Phone) applicationContext.getBean("phone");
System.out.println(phone);
5.打印结果
Phone(id=1, brand=小米, name=小米10)
这个就是通过静态工厂的方法来创建对象。
实例工厂
概念
实例工厂和静态工厂功能实际上是一样的,都是创建好对象,供我们去取。但是实例工厂需要先实例化工厂类,调用的是非静态方法,所以必须由对象来调用,不能用类来调用。在配置文件中需要先配置实例工厂的bean再配置Phone的bean。而在静态工厂中只需要配置Phone的bean即可,这是两者的区别。
代码示例
1.我们先创建一个Phone的类。
package com.xyj;
import lombok.Data;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Phone {
private int id;
private String name;
private String brand;
}
2.创建实例工厂类。
package factory;
import com.xyj.Phone;
import java.util.HashMap;
import java.util.Map;
public class InstanceFactory {
private Map<Integer, Phone> phoneMap;
public InstanceFactory() {
phoneMap = new HashMap<Integer,Phone>();
phoneMap.put(1,new Phone(1,"小米","小米10"));
phoneMap.put(2,new Phone(2,"华为","华为P50"));
phoneMap.put(3,new Phone(3,"荣耀","荣耀30"));
}
public Phone getPhone(int id){
return phoneMap.get(id);
}
}
3.配置实例工厂的bean和实力工厂创建的Phone的bean。
<!-- 配置实例工厂 bean-->
<bean id="phoneFactory" class="factory.InstanceFactory"></bean>
<!-- 配置实例工厂创建 Phone-->
<bean id="phone2" factory-bean="phoneFactory" factory-method="getPhone">
<constructor-arg value="2"></constructor-arg>
</bean>
5.打印结果
Phone(id=2, brand=华为, name=华为P50)
总结
两种工厂方法的作用功能是一样的,不同的就是静态方法和非静态方法的调用方式。