首页 > 其他分享 >实现Small-Spring

实现Small-Spring

时间:2024-03-21 18:56:37浏览次数:25  
标签:java 实现 Spring beanName bean Small pickle main com

《Spring 手撸专栏》第 3 章

目录结构

类关系

类分析:

  • BeanFactory接口:定义一个得到bean的接口
package main.java.com.pickle.springframework.factory;

import main.java.com.pickle.springframework.factory.config.BeanDefinition;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/3/21 15:20
 */
public interface BeanFactory {
    Object getBean(String beanName);
}

  • SingletonBeanRegistry接口:定义一个获得单例对象的接口
package main.java.com.pickle.springframework.factory.config;

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/3/21 16:05
 */
public interface SingletonBeanRegistry {
    Object getSingleton(String beanName);
}

  • DefaultSingletonBeanRegistry类:SingletonBeanRegistry的实现类,还有单例对象容器,实现了单例对象的注册和获取
package main.java.com.pickle.springframework.factory.support;

import main.java.com.pickle.springframework.factory.config.SingletonBeanRegistry;

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

/**
 * 持有一个单例容器,管理单例对象的存取
 *
 * @author Pickle
 * @version V1.0
 * @date 2024/3/21 16:06
 */
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {

    //单例对象容器
    private final Map<String, Object> singletonObjects = new HashMap<>();

    /**
     * 在容器中获取单例对象
     *
     * @param beanName 单例对象名称
     * @return 单例对象
     */
    @Override
    public Object getSingleton(String beanName) {
        return singletonObjects.get(beanName);
    }

    /**
     * 在容器中添加单例对象
     *
     * @param beanName        单例对象名称
     * @param singletonObject 单例对象
     */
    protected void addSingleton(String beanName, Object singletonObject) {
        singletonObjects.put(beanName, singletonObject);
    }

}

  • AbstractBeanFactory抽象类:实现了BeanFactory的接口
package main.java.com.pickle.springframework.factory.support;

import main.java.com.pickle.springframework.BeansException;
import main.java.com.pickle.springframework.factory.BeanFactory;
import main.java.com.pickle.springframework.factory.config.BeanDefinition;

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/3/21 16:11
 */
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {
    /**
     * @param beanName  bean name
     * @return  bean
     */
    @Override
    public Object getBean(String beanName) {
        //直接从单例容器中拿到bean对象
        Object bean = getSingleton(beanName);
        if (bean != null) {
            return bean;
        }
        //如果单例容器中拿不到,就去拿到该bean的注册信息,创建一个实例并保存到单例容器中
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        bean = createBean(beanName, beanDefinition);
        addSingleton(beanName, bean);
        return bean;
    }

    protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;

    protected abstract Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException;
}

  • BeanDefinitionRegistry接口:定义了BeanDefinition注册方法
package main.java.com.pickle.springframework.factory.support;

import main.java.com.pickle.springframework.factory.config.BeanDefinition;

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/3/21 16:44
 */
public interface BeanDefinitionRegistry {
    /**
     * 向注册表注册bean的class信息
     * @param beanName  beanName
     * @param beanDefinition bean的class的包装类
     */
    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
}

  • AbstractAutowireCapableBeanFactory抽象类:实现创建对象自动装入容器
package main.java.com.pickle.springframework.factory.support;

import main.java.com.pickle.springframework.BeansException;
import main.java.com.pickle.springframework.factory.config.BeanDefinition;

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/3/21 16:33
 */
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {
    @Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException {
        //创建bean,并且加入单例容器
        Object bean;
        try {
            bean = beanDefinition.getBeanClass().newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new BeansException("Instantiation of bean failed",e);
        }
        addSingleton(beanName,bean);
        return bean;
    }
}

  • DefaultListableBeanFactory类:Bean工厂
package main.java.com.pickle.springframework.factory.support;

import main.java.com.pickle.springframework.BeansException;
import main.java.com.pickle.springframework.factory.config.BeanDefinition;

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

/**
 * 存放bean的class注册信息
 *
 * @author Pickle
 * @version V1.0
 * @date 2024/3/21 16:46
 */
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry{
    private final Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>();

    @Override
    protected BeanDefinition getBeanDefinition(String beanName) throws BeansException {
        final BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) throw new BeansException("No bean named " + beanName + "is defined");
        return beanDefinition;
    }

    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName,beanDefinition);
    }
}

  • 异常类
package main.java.com.pickle.springframework;

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/3/21 16:25
 */
public class BeansException extends RuntimeException{
    public BeansException(String message) {
        super(message);
    }
    public BeansException(String message, Throwable cause) {
        super(message, cause);
    }
}

测试类

package test.java.com.pickle.springframeword.test.bean;

import main.java.com.pickle.springframework.entity.UserService;
import main.java.com.pickle.springframework.factory.config.BeanDefinition;
import main.java.com.pickle.springframework.factory.support.DefaultListableBeanFactory;
import org.junit.Test;

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/3/21 15:27
 */
public class UserServiceTest {
    @Test
    public void test_BeanFactory() {
        //1、初始化BeanFactory
        final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //2、注册bean
        beanFactory.registerBeanDefinition("userService", new BeanDefinition(UserService.class));
        //3、第一次获取bean
        final UserService userService = (UserService) beanFactory.getBean("userService");
        userService.queryUserInfo();        //查询用户信息
        //4、第二次获取bean
        final UserService userService_singleton = (UserService) beanFactory.getBean("userService");
        userService_singleton.queryUserInfo();  //查询用户信息
        //5、看看是不是单例
        System.out.println(userService == userService_singleton);   //true
    }

}


标签:java,实现,Spring,beanName,bean,Small,pickle,main,com
From: https://www.cnblogs.com/poteitoutou/p/18088035

相关文章

  • ChatGPT:实现高效论文写作的秘密武器
    ChatGPT无限次数:点击直达近年来,自然语言处理领域取得了巨大的进步,为研究人员提供了更高效的论文写作工具。其中,ChatGPT3.5Turbo作为一种强大的语言生成模型,为论文写作提供了秘密武器。在本文中,我们将介绍ChatGPT的功能和优势,并通过多个示例来展示其在高效论文写作中的应用......
  • 描述我处理过的一个性能优化问题&如何实现Web应用的负载均衡?
    一、描述我处理过的一个性能优化问题在我过去的工作经历中,我遇到并成功解决了一个性能优化问题。这个问题发生在一个电商网站的后台管理系统中,当管理员尝试查询大量订单数据时,系统的响应速度非常慢,有时甚至导致页面超时或崩溃。为了解决这个问题,我首先进行了性能分析。通过查......
  • 插件-js实现动态时钟效果
    <divid="updatetime"></div>constupdateTime=()=>{varnow=newDate();varyear=now.getFullYear();varmonth=now.getMonth()+1;//getMonth()返回0-11varday=now.getDate();varhours=now.getHour......
  • 解决SpringBoot环境下Redis哨兵模式连接失败问题,“NOAUTH Authentication required”
    io.lettuce.core.RedisCommandExceptionException:“NOAUTHAuthenticationrequired”在某行工作,项目上线代码,uat环境无异常,上到pp环境有问题,报redis连接不上;观察配置,发觉是apollo的配置是哨兵模式,有个哨兵密码。spring2.2.6RELEASE版本问题。于是写了全局配置,读取配置中......
  • java毕业设计线上牙科诊所管理推荐系统的设计与实现(springboot+mysql+jdk1.8+meven)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着互联网技术的飞速发展,越来越多的传统行业开始向数字化转型。医疗行业作为人们生活中的重要组成部分,其信息化、智能化的需求日益增长。牙科诊所作为提......
  • java毕业设计逍遥大药房管理系统(springboot+mysql+jdk1.8+meven)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着人们生活水平的提高,对健康的关注也日益增加。药房作为提供药品和健康咨询服务的重要场所,其管理效率和服务质量直接影响到人们的用药安全和健康。然而,......
  • java毕业设计小区宠物管理平台(springboot+mysql+jdk1.8+meven)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着社会的发展和人们生活水平的提高,越来越多的家庭开始饲养宠物。在城市中,小区是宠物活动的主要场所之一。然而,随着宠物数量的增加,小区宠物管理面临着许......
  • java毕业设计校园互助平台(springboot+mysql+jdk1.8+meven)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着互联网技术的飞速发展,人们的生活方式和学习方式都发生了翻天覆地的变化。特别是在校园环境中,学生们面临着各种各样的问题和需求,如学术问题、生活琐事......
  • go+gin webscoket 怎么实现心跳
    在Go+Gin中实现WebSocket的心跳,你需要一个WebSocket库,如gorilla/websocket。下面的例子展示了如何实现心跳机制:packagemainimport("net/http""time""github.com/gin-gonic/gin""github.com/gorilla/websocket")//升级器,用于将HTTP连接升......
  • SpringBoot建立websocket连接
    介绍WebSocket协议是一种基于TCP的协议,用于在客户端和服务器之间建立持久连接,并且可以在这个连接上实时地交换数据。WebSocket协议有自己的握手协议,用于建立连接,也有自己的数据传输格式。当客户端发送一个WebSocket请求时,服务器将发送一个协议响应以确认请求。在握手期间,......