欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

模仿spring的核心容器创建单例对象

程序员文章站 2024-03-24 16:32:28
...

模仿spring的核心容器创建单例对象

项目结构

模仿spring的核心容器创建单例对象

配置文件

  1. bean.properties

    accountService = com.xiaoge.service.impl.AccountServiceImpl
    accountDao = com.xiaoge.dao.impl.AccountDaoImpl
    

持久层接口

  1. AccountDao

    package com.xiaoge.dao;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/3/19 下午7:31
     * @Description: TODO
     */
    public interface AccountDao {
    
        public void saveAccount();
    
    }
    

持久层实现类

  1. AccountDaoImpl

    package com.xiaoge.dao.impl;
    
    import com.xiaoge.dao.AccountDao;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/3/19 下午7:31
     * @Description: TODO
     */
    public class AccountDaoImpl implements AccountDao {
        public void saveAccount() {
            System.out.println("保存成功!");
        }
    }
    

业务层接口

  1. AccountService

    package com.xiaoge.service;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/3/19 下午7:26
     * @Description: 账户业务层接口
     */
    public interface AccountService {
    
        /**
         * 模拟保存
         */
        public void saveAccount();
    
    }
    
    

业务层实现类

  1. AccountServiceImpl

    package com.xiaoge.service.impl;
    
    import com.xiaoge.dao.AccountDao;
    import com.xiaoge.factory.BeanFactory;
    import com.xiaoge.service.AccountService;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/3/19 下午7:28
     * @Description: 账户业务层实现类
     */
    public class AccountServiceImpl implements AccountService {
    
        private AccountDao accountDao = (AccountDao)BeanFactory.getBean("accountDao");
    
        public void saveAccount() {
            accountDao.saveAccount();
        }
    }
    

工厂

  1. BeanFactory

    package com.xiaoge.factory;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/3/19 下午7:54
     * @Description: TODO
     *
     * Bean, 在计算机英语中, 有可重用组件的含义.
     * JavaBean: 用java语言编写的可重用组件.
     *      javabean > 实体类
     *
     *    它就是创建我们的service和dao对象的.
     *
     *    第一个: 需要一个配置文件来配置我们的service和dao
     *           配置的内容: 唯一标识 = 全限定类名 (key = value)
     *
     *    第二个: 通过读取配置文件中配置的内容, 反射创建对象.
     *
     *    配置文件可以是xml也可以是properties
     */
    public class BeanFactory {
    
        private static Properties prop = null;
    
        // 定义一个map, 用于存放我们要创建的对象, 我们把它称职为容器
        private static Map<String, Object> beans;
    
        // 注意: 静态变量, 跟实例没关系, 静态变量只能出现在静态方法中, 值是会根据静态方法修改它而修改的
        // 而成员变量, 是根据实例走的, 每创建一个实例, 成员变量就会被初始化一遍
    
        // 在类加载的init阶段,类的类构造器中会收集所有的static块和字段并执行,static块只执行一次,由JVM保证其只执行一次。
        // 加载顺序: 一般顺序:静态块(静态变量)——>成员变量——>构造方法——>静态方法
        static {
            try {
    
                InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
    
                // 实例化对象
                prop = new Properties();
    
                prop.load(is);
    
                // 实例化容器
                beans = new HashMap<String, Object>();
    
                // 获取配置文件中的所有key
                Enumeration keys = prop.keys();
    
                // 遍历keys
                while(keys.hasMoreElements()) {
                    // 获取每一个key
                    String key = (String)keys.nextElement();
    
                    // 获取每个key对应的权限定类名
                    String ClassPath = prop.getProperty(key);
    
                    // 将全限定类名加载进内存, 并创建对象
                    Object value = Class.forName(ClassPath).newInstance();
    
                    // 将数据添加进map
                    beans.put(key, value);
                }
    
            } catch (IOException e) {
                throw  new ExceptionInInitializerError("初始化properties失败!");
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
        }
    
        /**
         * 根据Bean名称创建Bean对象 (单例)
         * @param beanName
         * @return
         */
        public static Object getBean(String beanName) {
            Object bean = null;
    
            // 获取map中对应键的值, 并且返回, 当map集合中没有该键, 直接抛出异常
            bean = beans.get(beanName);
    
            System.out.println(bean);
    
            return bean;
        }
    
        /**
         * 根据Bean名称获取Bean对象 (多例)
         * @param beanName
         * @return
    
            public static Object getBean(String beanName) {
                Object bean = null;
    
                String name = prop.getProperty(beanName);
    
                // 把权限定类名加载进内存, 并且创建一个实例化对象
                try {
                    bean = Class.forName(name).newInstance();
    
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
    
                return bean;
            }
         */
    
    }
    

main

  1. Client

    package com.xiaoge.ui;
    
    import com.xiaoge.factory.BeanFactory;
    import com.xiaoge.service.AccountService;
    
    /**
     * @Author: 潇哥
     * @DateTime: 2020/3/19 下午7:35
     * @Description: 模拟表现层, 调用业务层
     */
    public class Client {
    
        public static void main(String[] args) {
            // AccountService accountService = new AccountServiceImpl();
    
            for (int i = 0; i < 5; i++) {
                AccountService accountService = (AccountService)BeanFactory.getBean("accountService");
                accountService.saveAccount();
            }
    
    				// 运行结果
          	com.xiaoge.dao.impl.AccountDaoImpl@610455d6
            com.xiaoge.service.impl.AccountServiceImpl@511d50c0
            保存成功!
            com.xiaoge.service.impl.AccountServiceImpl@511d50c0
            保存成功!
            com.xiaoge.service.impl.AccountServiceImpl@511d50c0
            保存成功!
            com.xiaoge.service.impl.AccountServiceImpl@511d50c0
            保存成功!
            com.xiaoge.service.impl.AccountServiceImpl@511d50c0
            保存成功!
    
        }
    
    
    
    }