Spring IoC工厂方法

146 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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)

总结

两种工厂方法的作用功能是一样的,不同的就是静态方法和非静态方法的调用方式。