IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 手撸一个Spring容器 -> 正文阅读

[Java知识库]手撸一个Spring容器

1、创建你的pojo对象

package cn.pojo;

/**
 * @author zhr_java@163.com
 * @date 2022/4/17 22:03
 */
public class UserDao {
    public void queryUserInfo(){
        System.out.println("hello world!!!");
    }
}

2、创建resources文件夹并创建beans.properties文件

注意:cn.pojo.UserDao要对应填写你自己创建的

userDao:cn.pojo.UserDao

在这里插入图片描述

3、定义Bean

package cn.bean;

/**
 * bean定义类,配置文件中bean定义对应的实体
 *
 * @author zhr_java@163.com
 * @date 2022/4/17 21:56
 */
public class BeanDefinition {
  private String beanName;

  private Class beanClass;

  public String getBeanName() {

    return beanName;
  }

  public void setBeanName(String beanName) {

    this.beanName = beanName;
  }

  public Class getBeanClass() {

    return beanClass;
  }

  public void setBeanClass(Class beanClass) {

    this.beanClass = beanClass;
  }
}

4、资源加载

package cn.utils;

import cn.bean.BeanDefinition;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

/**
 * @author zhr_java@163.com
 * @date 2022/4/17 22:12
 */
public class ResourceLoader {
  public static Map<String, BeanDefinition> getResource() {
    Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>(16);
    Properties properties = new Properties();
    try {
      InputStream inputStream = ResourceLoader.class.getResourceAsStream("/beans.properties");
      properties.load(inputStream);
      Iterator<String> it = properties.stringPropertyNames().iterator();
      while (it.hasNext()) {
        String key = it.next();
        String className = properties.getProperty(key);
        BeanDefinition beanDefinition = new BeanDefinition();
        beanDefinition.setBeanName(key);
        Class clazz = Class.forName(className);
        beanDefinition.setBeanClass(clazz);
        beanDefinitionMap.put(key, beanDefinition);
      }
      inputStream.close();
    } catch (IOException | ClassNotFoundException e) {
      e.printStackTrace();
    }
    return beanDefinitionMap;
  }
}

5、Bean注册

package cn.bean;

import java.util.HashMap;
import java.util.Map;

/**
 * 对象注册器,这里用于单例bean的缓存,我们大幅简化,默认所有bean都是单例的。可以看到所谓单例注册,也很简单,不过是往HashMap里存对象。
 *
 * @author zhr_java@163.com
 * @date 2022/4/17 21:59
 */
public class BeanRegister {

  /** 单例Bean缓存 */
  private Map<String, Object> singletonMap = new HashMap(32);

  /**
   * 获取单例Bean
   *
   * @param beanName bean名称
   * @return
   */
  public Object getSingletonBean(String beanName) {
    return singletonMap.get(beanName);
  }

  /**
   * 注册单例bean
   *
   * @param beanName
   * @param bean
   */
  public void registerSingletonBean(String beanName, Object bean) {
    if (singletonMap.containsKey(beanName)) {
      return;
    }
    singletonMap.put(beanName, bean);
  }
}

6、对象工厂

package cn.factory;

import cn.bean.BeanDefinition;
import cn.bean.BeanRegister;
import cn.utils.ResourceLoader;

import java.util.HashMap;
import java.util.Map;

/**
 * 获取bean的时候,先从单例缓存中取,如果没有取到,就创建并注册一个bean
 *
 * @author zhr_java@163.com
 * @date 2022/4/17 22:00
 */
public class BeanFactory {
  private Map<String, BeanDefinition> beanDefinitionMap = new HashMap();

  private BeanRegister beanRegister;

  public BeanFactory() {
    // 创建bean注册器
    beanRegister = new BeanRegister();
    // 加载资源
    this.beanDefinitionMap = ResourceLoader.getResource();
  }

  /**
   * 获取bean
   *
   * @param beanName bean名称
   * @return
   */
  public Object getBean(String beanName) {
    // 从bean缓存中取
    Object bean = beanRegister.getSingletonBean(beanName);
    if (bean != null) {
      return bean;
    }
    // 根据bean定义,创建bean
    return createBean(beanDefinitionMap.get(beanName));
  }

  /**
   * 创建Bean
   *
   * @param beanDefinition bean定义
   * @return
   */
  private Object createBean(BeanDefinition beanDefinition) {
    try {
      Object bean = beanDefinition.getBeanClass().newInstance();
      // 缓存bean
      beanRegister.registerSingletonBean(beanDefinition.getBeanName(), bean);
      return bean;
    } catch (InstantiationException | IllegalAccessException e) {
      e.printStackTrace();
    }
    return null;
  }
}

7、测试

package cn;

import cn.factory.BeanFactory;
import cn.pojo.UserDao;

/**
 * @author zhr_java@163.com
 * @date 2022/4/17 22:03
 */
public class ApiTest {
  public static void main(String[] args) {
      //1.创建bean工厂(同时完成了加载资源、创建注册单例bean注册器的操作)
      BeanFactory beanFactory = new BeanFactory();

      //2.第一次获取bean(通过反射创建bean,缓存bean)
      UserDao userDao1 = (UserDao) beanFactory.getBean("userDao");
      userDao1.queryUserInfo();

      //3.第二次获取bean(从缓存中获取bean)
      UserDao userDao2 = (UserDao) beanFactory.getBean("userDao");
      userDao2.queryUserInfo();
  }
}

效果图:

在这里插入图片描述
总结:实际上先通过spi的方式把编译前的bean资源加载,在工厂方法中初始化,在调用bean的时候通过单例的方式获取,如果是第一次获取就通过加载过的资源实例化bean,如果不是就根据bean名称返回bean

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:27:33  更:2022-04-18 17:28:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:04:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码