Spring中的工厂设计模式

引言

spring是一个轻量级的javaee解决方案,整合众多优秀设计模式(设计模式是指:面向对象设计中,解决特定问题的经典代码)。spring中最常用的设计模式是工厂设计模式,工厂设计模式解决了创建对象的耦合问题,下面我将带大家了解spring是如何利用工厂模式创建对象的。

工厂模式是什么?

工厂模式是23种设计模式中的一种,思想是通过工厂类创建对象。下面我们模拟一下简单的工厂模式,让大家直观感受一下工厂模式解决了什么问题。首先我们准备一个StudentService接口及其实现类:

//学生服务接口
public interface StudentService {
    //登录
    public boolean login(String userName,String passWord);
}
//学生服务实现类
public class StudentServiceImpl implements StudentService{
    //登录
    public boolean login(String userName,String passWord){
        System.out.println("login-->userName="+userName+",passWord="+passWord);
        return true;
    }
}

在初学java时,我们使用一个类时会new一个对象,代码如下:

//测试
public class Test {
    public static void main(String[] args) {
        //创建对象
        StudentService studentService = new StudentServiceImpl();
        studentService.login("zhangsan","123");

        //输出结果:login-->userName=zhangsan,passWord=123
    }
}

而使用工厂模式创建对象时,我们需要创建一个工厂类,再调用工厂类的对应方法创建对象,首先创建工厂类:

//工厂类
public class Factory {
    //该方法返回学生服务对象
    public static StudentService getStudentService(){
        return new StudentServiceImpl();
    }
}

工厂模式创建对象:

//测试,工厂类创建对象
public class Test {
    public static void main(String[] args) {

        //使用工厂类的对应方法创建学生服务对象
        StudentService studentService = Factory.getStudentService();
        studentService.login("zhangsan","123");

        //输出结果:login-->userName=zhangsan,passWord=123
    }
}

实际上,工厂模式就是用一个工厂类统一创建对象,通过对比我们发现工厂模式创建对象比传统new对象的方式更复杂了,好像还没啥用,这不多此一举吗?

为什么spring不使用new创建对象?

这就要提到开闭原则 (Open Close Principle):对扩展开放,对修改关闭。假设我们推出了StudentService接口的第二代实现类StudentServiceImpl02,使用new的方式,我们需要修改源码,违背了对修改关闭的原则。上诉工厂模式虽然减少了代码的修改量,但还是需要修改源码。spring的工厂类并不是通过new创建对象的,而是通过反射创建对象,彻底解决了代码耦合的情况。
(不了解反射的朋友可以通过这篇博客了解反射机制https://blog.csdn.net/qq_45874107/article/details/114498777)。

spring中的反射工厂

下面我们看看spring是如何通过反射解决代码耦合问题的。首先我们采用反射机制改变上诉例子的工厂代码

//通过反射机制创建对象的工厂类
public class Factory {
    //该方法返回学生服务对象
    public static StudentService getStudentService(){
        StudentService studentService = null;
        try {
            //获取StudentServiceImpl类
            Class studentServiceclass = Class.forName("StudentServiceImpl");
            //通过反射创建对象
            studentService = (StudentService) studentServiceclass.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return studentService;
    }
}

细心的网友会发现还是需要修改传入Class.forName()中的字符串才能创建我们新推出的第二代实现类。spring采用配置文件的形式传入参数,我们这里用properties配置文件模拟spring的配置文件传参,下面我们介绍一下properties。
properties是以键值对的方式存储数据的,继承结构图如下:
继承结构图
它的特点是key和value都只能是字符串。

说回spring的反射工厂,有了配置文件之后,我们就不需要Class.forName()中写死某一字符串了,而是通过key读取配置文件中的value,首先创建一个properties配置文件,内容如下:
创建的配置文件以及配置文件内容
将上诉工厂类写死的字符串改为通过key读取到的value,加上properties文件读取的代码后,工厂类变成:

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

//通过反射机制创建对象的工厂类
public class Factory {
    //创建一个properties
    public static Properties properties = new Properties();

    //静态代码块,类加载时期将配置文件内容封装到properties中
    static{
        //获取I/O流
        InputStream inputStream = Factory.class.getResourceAsStream("student.properties");
        //文件内容封装到properties中
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //关闭流
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //该方法返回学生服务对象
    public static StudentService getStudentService(){
        StudentService studentService = null;
        try {
            //获取StudentServiceImpl类
            Class studentServiceclass = Class.forName(properties.getProperty("studentService"));
            //通过反射创建对象
            studentService = (StudentService) studentServiceclass.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return studentService;
    }
}

测试结果:

//测试,工厂类创建对象
public class Test {
    public static void main(String[] args) {

        //使用工厂类的对应方法创建学生服务对象
        StudentService studentService = Factory.getStudentService();
        studentService.login("zhangsan","123");

        //输出结果:login-->userName=zhangsan,passWord=123
    }
}

这样我们就实现了改变配置文件内容就能创建我们新推出的第二代实现类,同时不修改源码。

总结

我们讲述了spring中最常用工厂设计模式的原理和为什么使用工厂设计模式,同时以简化的代码重现了spring框架是如何创建对象的,希望对大家有所帮助。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring框架,常用的设计模式包括: 1. 依赖注入(Dependency Injection):Spring使用依赖注入模式来管理对象之间的依赖关系。通过将对象的依赖关系交由容器来管理,实现了松耦合和可测试性。 2. 单例模式(Singleton):Spring默认使用单例模式来管理Bean对象。这意味着在整个应用程序,只会创建一个实例,并且该实例会被共享和重用。 3. 工厂模式(Factory):Spring使用工厂模式来创建和管理Bean对象。通过配置文件或注解,Spring可以根据需要创建相应的Bean。 4. 代理模式(Proxy):Spring使用代理模式来实现AOP(面向切面编程)。通过代理对象,可以在方法调用前、后或异常抛出时执行额外的逻辑,例如日志记录、事务管理等。 5. 观察者模式(Observer):Spring的事件机制基于观察者模式。通过定义事件和监听器,可以实现对象间的解耦和消息通知。 6. 模板方法模式(Template Method):Spring的JdbcTemplate是一个典型的模板方法模式的应用。它定义了一系列执行数据库操作的步骤,具体的实现由子类提供。 7. 委托模式(Delegation):Spring的委托模式主要体现在IOC容器的实现。容器负责管理对象的创建、配置和生命周期,将这些任务委托给相应的Bean工厂和处理器。 这些设计模式Spring被广泛应用,帮助开发者实现可维护、可扩展和可测试的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值