Spring学习( 一 ):程序的解耦和自己设计一个BeanFactory

Spring学习( 一 ):程序的解耦和自己设计一个BeanFactory

前言

我们在学习完工厂模式之后,发现网上给的例子,根本体现不了工厂模式的作用。先不说存在有的例子本身就是错误的,主要是例子中的代码太简单,可以说没必要用工厂模式,只不过是为了说明实现方式和原理。所以,会产生一种错觉:还不如直接new 一个对象来的方便,有效。

一、介绍一下工厂模式(重点)

我们先介绍一下工厂模式的好处,然后再开始用简单的例子来演示工厂模式的实现。

1、工厂模式是为了解耦:把对象的创建和使用的过程分开。就是Class A 想调用 Class B ,那么A只是调用B的方法,而至于B的实例化,就交给工厂类。
2、工厂模式能减少大量重复代码,如果A类要使用B,如果创建B的过程很复杂,且很多类都使用B,那么会产生大量重复代码。如果这个时候要把B改为B的子类,那么要在很多地方修改创建类的方法
3、很多时候单例已经能满足程序的需求,那么通过 new 创建出来的类是多例,降低了程序的性能。

所以工厂模式能解决这么多问题,我们为什么还要使用new呢?

二、工厂模式的演示

2、创建application.properties 里面存beanName和类名全路径

userService=com.service.impl.UserServiceImpl
userDao=com.dao.impl.UserDapImpl

2、创建一个BeanFactory

这个工厂创建出来的不是单例对象,后面还要做改造。

public class BeanFactory {
    private static Properties properties;

    // 1、通过静态代码块对Properties初始化
    static {
        try {
            properties = new Properties();
            // 2、获取properties的文件流
            InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream("application.properties");
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Object getBean(String beanName){
        Object bean = null;
        try {
        	// 通过beanName获取类名全路径
            String property = properties.getProperty(beanName);
            bean = Class.forName(property).newInstance();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return bean;
    }
}

3、测试

public class UserController {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            UserService bean = (UserService) BeanFactory.getBean("userService");
            System.out.println(bean);
            System.out.println(bean.getUser("张三"));
        }
    }
}

可以看到每个对象都不一样,所以说多例。
在这里插入图片描述

4、改造成单例工厂

创建一个容器(Map)key为beanName,value为创建出来的实例。这样每次从HashMap拿到的对象都是同一个。

public class BeanFactory {
    private static Properties properties;
    private static Map<String,Object> beans;
    // 通过静态代码块对Properties初始化
    static {
        try {
            properties = new Properties();
            beans = new HashMap<>();
            // 2、获取properties的文件流
            InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream("application.properties");
            properties.load(inputStream);
            Enumeration<Object> keys = properties.keys();
            while (keys.hasMoreElements()){
                String beanName = (String) keys.nextElement();
                String className = properties.getProperty(beanName);
                Object bean = Class.forName(className).newInstance();
                beans.put(beanName,bean);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Object getBean(String beanName){
        return beans.get(beanName);
    }
}

5、写在最后

本文代码已上传到GitHub上面了,需要请直接私信我。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值