一、从工厂模式到Spring的分析(一)

通过反射创建对象,尽量少的使用new()创建对象是降低类与类之间耦合度方法,我们先来看看工厂模式创建对象的一个简单的实例
首先创建一个UserDao接口

package com.lp.dao;

/**
 * @Date 2020/5/26 21:19
 * @Author luopeng
 */
public interface UserDao {
    void saveUser();
}

创建接口实现类

package com.lp.dao.impl;

import com.lp.dao.UserDao;
import com.lp.factory.Factory;

/**
 * @Date 2020/5/26 21:20
 * @Author luopeng
 */
public class UserDaoImpl implements UserDao {

    public void saveUser() {
        System.out.println("保存成功!");
    }
}

service层接口

package com.lp.service;

/**
 * @Date 2020/5/26 21:18
 * @Author luopeng
 */
public interface UserService {
    void saveUser();
}

接口实现类

package com.lp.service.impl;

import com.lp.dao.UserDao;
import com.lp.dao.impl.UserDaoImpl;
import com.lp.factory.Factory;
import com.lp.service.UserService;

/**
 * @Date 2020/5/26 21:21
 * @Author luopeng
 */
public class UserServiceImpl implements UserService {


    public void saveUser() {
        UserDao userDao = Factory.getBean("userDao");
        userDao.saveUser();

    }
}

创建工厂类实现反射创建对象

package com.lp.factory;

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

/**
 * @Date 2020/5/26 21:25
 * @Author luopeng
 */
public class Factory {
    private static Properties pro = new Properties();

    static {
        try {

            InputStream inputStream = Factory.class.getClassLoader().getResourceAsStream("bean.properties");
            pro.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static <T> T getBean(String beanName) {
        String property = pro.getProperty(beanName);

        Object newInstance = null;
        try {
            //通过反射创建对象
            newInstance = Class.forName(property).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T) newInstance;

        }


}

写测试类

package com.lp.ui;

import com.lp.factory.Factory;
import com.lp.service.UserService;

/**
 * @Date 2020/5/26 21:21
 * @Author luopeng
 */
public class test {
    public static void main(String[] args) {

        for (int j = 0; j <5 ; j++) {
            UserService userService = Factory.getBean("userService");
            userService.saveUser();
            System.out.println(userService);
        }
    }
}


运行后的结果截图在这里插入图片描述

此时我们会发现每次程序都会新创建对象,这显然是一个多例,而对于我们此时来讲,为了提高程序的效率,我们更愿意是单例的,此时我们需要对工厂类进行重新设计!

  • 首先讲一下想法和思路:对于配置文件中的信息,我们需要创建对象来供使用,我的方法是通过一个Map集合来将对象存储在里面,需要用这个对象时只需要传入key即可。
  • 我们怎么来创建对象呢?首先我们需要把配置文件中的key拿到,我有两种方法来拿,keys()和keyset(),过程大同小异,代码中两种方式我都有写。
  • 拿到了过后我们需要的是遍历拿到的key,然后通过key来得到其value,通过反射来创建对象,将创建的对象存在我们定义好的容器Map中。
  • 这些操作我们在静态代码块中进行操作,即类一加载就创建好对象,且只创建一次,最后要用的时候从容器里面取出来就行了!
package com.lp.factory;

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

/**
 * @Date 2020/5/26 21:25
 * @Author luopeng
 */
public class Factory {
    private static Properties pro;
    private static Map<String, Object> beans;

    static {
        try {
            pro = new Properties();
            InputStream inputStream = Factory.class.getClassLoader().getResourceAsStream("bean.properties");
            pro.load(inputStream);
            //实例化容器
            beans = new HashMap<String, Object>();
            //取出配置文件中的key
  /*          Set<Object> keys = pro.keySet();
            //遍历取出每一个key
            for (Object key : keys) {
                //根据key从配置文件中取得value(即类路径)的值
                String classPath = pro.getProperty((String) key);
                //通过反射创建对象
                Object value = Class.forName(classPath).newInstance();

                //将key和value存入我们的容器里面
                beans.put((String) key, value);
            }*/


            Enumeration<Object> keys = pro.keys();
            //遍历取出每一个key
            while (keys.hasMoreElements()) {
                String key = keys.nextElement().toString();
                //根据key从配置文件中取得value的值
                String classPath = pro.getProperty(key);
                //通过反射创建对象
                Object value = Class.forName(classPath).newInstance();
                //将key和value存入我们的容器里面
                beans.put((String) key, value);
            }

            } catch(IOException e){
                e.printStackTrace();
            } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

        public static <T > T getBean(String beanName) {
/*        String property = pro.getProperty(beanName);

        Object newInstance = null;
        try {
            //通过反射创建对象
            newInstance = Class.forName(property).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T) newInstance;*/
            return (T) beans.get(beanName);

        }


    }

这是成功运行后的结果!

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值