← 返回首页
Spring基础教程(十九)
发表时间:2020-10-09 12:09:54
工厂模式注入bean

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

工厂模式实现思路的UML图如下:

Spring可以通过工厂模式来注入bean。

实例: 项目结构图如下。

实现步骤: 1.设计接口类

package com.repository;

//usb接口,实现设备读和写两个抽象方法
public interface UsbDevice {
    void read(); //设备读
    void write(String content); //设备写
}

2.设计具体产品类

package com.entity;

import lombok.Data;
//抽象磁盘类
@Data
public abstract class Disk {

    protected String brand; //磁盘的品牌
    protected int size; //磁盘容量 1G/1T

    public Disk() {
    }

    public Disk(String brand, int size) {
        this.brand = brand;
        this.size = size;
    }
}
package com.entity;

import com.repository.UsbDevice;
import lombok.Data;
//移动硬盘类,实现了USB接口
@Data
public class MovedDisk  extends Disk implements UsbDevice {

    private MovedDisk() {
    }

    private MovedDisk(String brand, int size) {
        super(brand, size);
    }

    public void read() {
        System.out.println(this.brand+"牌,容量为:"+this.size+",移动硬盘正在读取数据...");
    }

    public void write(String content) {
        System.out.println(this.brand+"牌,容量为:"+this.size+",移动硬盘正在写入数据:"+content);
    }
}
package com.entity;

import com.repository.UsbDevice;
import lombok.Data;

//U盘,一种具体产品。实现了usb接口
@Data
public class Udisk extends Disk implements UsbDevice {

    private Udisk() {
    }

    private Udisk(String brand, int size) {
        super(brand, size);
    }

    public void read() {
        System.out.println(this.brand+"牌,容量为:"+this.size+",U盘正在读取数据...");
    }

    public void write(String content) {
        System.out.println(this.brand+"牌,容量为:"+this.size+",U硬盘正在写入数据:"+content);
    }
}
package com.entity;

import com.repository.UsbDevice;

//电器类,使用某种usb设备进行读写。
public class Machine {

    //private UsbDevice device;
    public void work(UsbDevice device,String content){
        device.read();
        device.write(content);
    }
}

3.设计USB设备枚举类型常量

package com.factory;

//定义一些常见的USB设备类型
public enum UsbDeviceType {
    UDISK,MOVEDISK,MOBILE,PRINTER; //U盘,移动硬盘,手机,打印机
}

4.设计工厂类

package com.factory;

import com.entity.Udisk;
import com.repository.UsbDevice;
import java.lang.reflect.Constructor;

//生产各个usb设备的工厂
public class UsbDeviceFactory {

    public static UsbDevice makeUsbDevice(UsbDeviceType type,String brand,int size) throws Exception {
        Class clazz ; //类对象。
        Constructor constructor;
        UsbDevice obj = null;
        switch (type) {
            case UDISK:

                clazz = Class.forName("com.entity.Udisk");
                constructor = clazz.getDeclaredConstructor(String.class,int.class);
                constructor.setAccessible(true);
                obj = (UsbDevice) constructor.newInstance(new Object[]{brand,size});
                break;

            case MOVEDISK:
                clazz = Class.forName("com.entity.MovedDisk");
                constructor = clazz.getDeclaredConstructor(String.class,int.class);
                constructor.setAccessible(true);
                obj = (UsbDevice) constructor.newInstance(new Object[]{brand,size});
                break;
            case MOBILE:
                System.out.println("准备生产手机...");
                break;
            case PRINTER:
                System.out.println("准备生产打印机...");
                break;
        }
        return obj;
    }
}

5.在applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--配置工厂对象-->
    <bean id="disk" class="com.factory.UsbDeviceFactory" factory-method="makeUsbDevice" scope="prototype">
        <constructor-arg name="brand">
            <null></null>
        </constructor-arg>
        <constructor-arg name="size">
            <null></null>
        </constructor-arg>
        <constructor-arg name="type">
            <null></null>
        </constructor-arg>
    </bean>
</beans>

6.编写测试类测试

package com.factory;

import com.repository.UsbDevice;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UsbDeviceFactoryTest {
    private static ApplicationContext context;
    @BeforeClass
    public static void initContext(){
        context = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
    @Test
    public void testGetBeanByFactory(){
       UsbDevice device = (UsbDevice) context.getBean("disk",new Object[]{UsbDeviceType.UDISK,"samsung",5000});
        device.read();
        device.write("helloworld");
    }
}

运行效果:
samsung牌,容量为:5000,U盘正在读取数据...
samsung牌,容量为:5000,U硬盘正在写入数据:helloworld