程序员社区

12. Spring 工厂方法

Spring 工厂方法

IOC 是典型的工厂模式,现在来学习如何使用工厂模式来创建 bean。

说明:在学习这一部分内容之前,请读者自行复习或者补充设计模式中工厂模式的这一部分背景知识,要知道创建一个对象时,采用工厂模式不是多此一举,而是对象的初始化非常有必要的操作。如果对这个不了解,那么阅读本文时,会觉得这种既操作多余,也不甚理解。

漫画:设计模式之“工厂模式”
IoC 通过模式创建 bean 有两种方式:

  1. 静态工厂方法
  2. 实例工厂方法

1. 静态工厂方法

第一步:创建 Car 实体类;

package com.trainingl.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Car {
    private int num;
    private String brand;
}

第二步:创建静态工厂类,静态工厂方法;

package com.trainingl.Factory;

import com.trainingl.entity.Car;

import java.util.HashMap;
import java.util.Map;

public class StaticCarFactory {
    private static Map<Integer,Car> cars;

    static {
        cars = new HashMap<Integer, Car>();
        cars.put(1,new Car(1,"奥迪"));
        cars.put(2,new Car(2,"奥拓"));
        cars.put(3,new Car(3,"奔驰"));
        cars.put(4,new Car(4,"宝马"));
    }

    public static Car getCar(int num){
        return cars.get(num);
    }
}

第三步:在 spring.xml 中配置静态工厂;

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
	   http://www.springframework.org/schema/context
	   http://www.springframework.org/schema/context/spring-context-4.3.xsd
">
    <!--配置静态工厂创建Car对象-->
    <bean id="car1" class="com.trainingl.Factory.StaticCarFactory" factory-method="getCar">
        <constructor-arg value="1"></constructor-arg>
    </bean>
</beans>
  1. factory-method 指向类的静态方法;
  2. constructor-arg 的 value 属性为调用静态方法所传的参数;

第四步:在测试类中直接获取 car1 对象;

package com.trainingl.test;

import com.trainingl.entity.Car;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Car car = (Car)applicationContext.getBean("car1");
        System.out.println(car);
    }
}

12. Spring 工厂方法插图


2. 实例工厂方法

第一步:创建实例工厂类,工厂方法;

package com.trainingl.Factory;

import com.trainingl.entity.Car;

import java.util.HashMap;
import java.util.Map;

public class InstanceCarFactory {
    private Map<Integer, Car> carMap;
    public InstanceCarFactory(){
        carMap = new HashMap<Integer, Car>();
        carMap.put(1,new Car(1,"本田"));
        carMap.put(2,new Car(2,"奥迪"));
        carMap.put(3,new Car(3,"宝马"));
    }
    public Car getCar(Integer num){
        return carMap.get(num);
    }
}

第二步:spring.xml 中配置 bean;

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
	   http://www.springframework.org/schema/context
	   http://www.springframework.org/schema/context/spring-context-4.3.xsd
">
    
    <!--配置实例工厂对象-->
    <bean id="carFactory" class="com.trainingl.Factory.InstanceCarFactory"></bean>
    
    <!--通过实例工厂对象创建car对象-->
    <bean id="car2" factory-bean="carFactory" factory-method="getCar">
        <constructor-arg value="2"></constructor-arg>
    </bean>
    
</beans>
  1. factory-bean 指向实例化的工厂对象;
  2. factory-method 指向实例工厂对象的非静态方法;
  3. constructor-arg 的 value 属性为调用非静态方法所传的参数;

第三步:在测试类中直接获取 car2 对象;

package com.trainingl.test;

import com.trainingl.entity.Car;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Car car = (Car)applicationContext.getBean("car2");
        System.out.println(car);
    }
}

在这里插入图片描述

对比两种方式的区别

  1. 静态工厂方法的方式创建 Car 对象,不需要实例化工厂对象,因为静态工厂的静态方法不需要创建对象即可调用,所以 spring.xml 只需要配置一个 Car bean,而不需要配置工厂 bean。

  2. 实例工厂方法创建 car 对象,必须先实例化工厂对象,因为调用的非静态方法,必须通过对象调用,不能直接通过类来调用,所以 spring.xml 中需要先配置工厂 bean,再配置 Car 的 bean。

两种方式的区别,本质上还是静态方法与非静态方法调用的不同。

赞(0) 打赏
未经允许不得转载:IDEA激活码 » 12. Spring 工厂方法

一个分享Java & Python知识的社区