• 【无标题】


    博客主页:JavaProfessional
    一个专注于Java的博主,致力于使用通俗易懂的语句讲解内容,期待您的关注!

    前言

    读完本篇你将获得:

    1. 理解Spring IOC的架构图
    2. 理解Spring IOC中主要类的职责。
    3. 从设计模式出发理解Spring的精妙之处,学习大神写代码的精髓,多学习多实践相信我们都可以写出如此精妙的代码。

    第一步:从IOC中获取第一个JavaBean

    点击这里

    第二步:从Main出发

    本次讲解都是基于第一步实现的程序,不是很复杂,却是Spring的核心,学习之前请实践一下哦~

    以下是主程序,也是我们的入口:

    public class Main {
        public static void main(String[] args) {
            ApplicationContext springContext = new ClassPathXmlApplicationContext("spring-context.xml");
            User user = springContext.getBean("user", User.class);
            System.out.println(String.format("userName:%s", user.getUserName()));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    我们发现我们最核心的功能getBean方法是来自一个叫ClassPathXmlApplicationContext的类。现在我们不深入源码,如果让你实现这个getBean你会怎样实现?

    public class ClassPathXmlApplicationContext{
        private HashMap<String, Object> beanMap;
    
        ClassPathXmlApplicationContext(String configFileName) {
            // 读取配置文件,略
            // 解析配置文件,略
            // 循环读取配置文件的bean配置,反射生成对象,放入map中,等待getBean调用
            beanMap.put("beanName"BeanClass.newInstance());
        }
    
        public Object getBean(String beanName) {
            return beanMap.get(beanName);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    这样做非常好,我们的第一个版本满足了IOC的最基本要求。能做到这里其实已经实现了Spring的核心,对吗?其余的都是添砖加瓦让这个框架更好。
    那我们打开ClassPathXmlApplicationContext看一下他是如何实现的吧!(使用idea的diagram功能)
    在这里插入图片描述

    好家伙,怎么这么复杂,想必大家都有恐惧之心。但其实我们抓住核心,ClassPathXmlApplicationContext类里面没有getBean方法,那么getBean到底是从哪里来的?我们一路往上追溯,发现ClassPathXmlApplicationContext继承了太多的类,但是有一个类有getBean方法,于是ClassPathXmlApplicationContext也就有了getBean方法,这个类就是BeanFactory
    在这里插入图片描述

    我们精简一下,看一下大神是怎样写代码的:

    public interface BeanFactory {
        Object getBean(String beanName);
    }
    
    public abstract class AbstractApplicationContext implements BeanFactory{
        public abstract BeanFactory getBeanFactory();
        
        public getBean(String beanName) {
            return this.getBeanFactory().getBean(beanName);
        }
    }
    public ClassPathXmlApplicationContext extends AbstractApplicationContext {
        Resource[] resources;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    为什么要这么写?大神为社么要这么写呢?是故意让其显得复杂吗?其实并不是,这其中使用了一种设计模式——模板模式,为了解决重复代码问题。其中这个AbstractApplicationContext就是模板。

    试想我们不仅要从ClassPath路径下读取XML文件的形式读取配置文件,我们还需要从文件系统中,从注解中读取等等方式,有一部分的代码其实是重复的,我们就都实现一遍吗?这时候就可以使用模板模式,用于减少重复代码。

    好文推荐

    1. 通俗易懂JVM
    2. 为什么Spring中的IOC(控制反转)能够降低耦合性(解耦)?
    3. 效率翻倍,这些idea的逆天功能你知道吗?
  • 相关阅读:
    C# CAD 框选pdf输出
    河南直销系统开发对直销行业有何帮助?
    VIT中的einops包详解
    电商仓储物流是什么?
    this硬绑定
    ECharts快速入门
    FTP客户端c代码功能实现
    Linux运行环境搭建系列-Flink安装
    go学习之接口知识
    DOTA-PEG-麦芽糖 maltose-DOTA 麦芽糖-四氮杂环十二烷四乙酸
  • 原文地址:https://blog.csdn.net/tinpo_123/article/details/125437065