springIOC源码解析(一)

本文通过一个简单的示例,介绍了Spring框架如何管理Bean的过程,包括读取配置文件、解析配置文件、初始化Bean等步骤,并深入探讨了BeanFactory和ApplicationContext两种初始化方式的区别。

spring源码我也不是很了解,原来几次下定决心去看但一直不知道入口在哪里,但这是进阶必须要迈过的一个坎,下面我按照自己现在的思路来对spring源码进行阅读,首先从spring如何管理bean开始
首先咱们看看spring管理bean的一个小demo

public class Test {
    public static void main(String[] args) {
        /**
         * 首先看看spring怎么对bean进行初始化,一般来说有两种办法
         * 1、使用beanFactory
         * 2、使用applicationContext
         * 下面我分别使用两种方式进行初始化,并看看两种方式的源码有何不同
         */
        //使用beanFactory
        Resource resource = new ClassPathResource("springresourceConfiguration.xml");
        BeanFactory beanFactory = new XmlBeanFactory(resource);
        Engine engine = (Engine)beanFactory.getBean("engine");
        System.out.println(engine.toString());
        Car car = (Car)beanFactory.getBean("car");
        car.introduce();




        //使用applicationContext
        ApplicationContext ctx = new ClassPathXmlApplicationContext("springresourceConfiguration.xml");
        Engine e = (Engine)ctx.getBean("engine");
        System.out.println(e.toString());
        Car c = (Car)ctx.getBean("car");
        c.introduce();
    }
}

springresourceConfiguration.xml配置文件如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        ">
    <bean id="car" class="com.kevindai.IOCresourcecode.Car">
        <property name="engine" ref="engine" />
    </bean>
    <bean id="engine" class="com.kevindai.IOCresourcecode.Engine"></bean>
</beans>

Car和Engine的代码很简单我就不帖出来了

这样一个spring管理bean的demo就出来了,首先咱们思考一下上面一个demo的经历了哪些流程,我个人认为至少有一下几步
1、读取配置文件
2、解析配置文件
3、把解析出来的bean交给spring管理
4、按照一定的对应关系把bean组装起来(car中需要engine)
5、初始化bean
这个是我个人的观点,不一定准确,但咱们可以顺着这个思路看下去,然后跟源码对比看看思路是否正确,OK,源码阅读开始
首先看第一行Resource resource = new ClassPathResource(“springresourceConfiguration.xml”);这个应该跟咱们思路一致是用于读取配置文件的,看看spring源码中如何处理
这里写图片描述
上图中能看到,读取配置文件时最主要做了两件事:
1、获取配置文件路径
2、初始化classLoader
———————————————————————————————————————————————————————
这里可能有些同学就要问了,获取配置文件路径好理解,那classLoader又是什么呢?这里简单解释一下:
classLoader是类装载器,在java.lang包中,它是一个重要的JRE组件,负责在运行时查找和装载Class文件.也就是说所有的类都能通过全限定类名从classLoader中获取类信息.———————————————————————————————————————————————————————
然后看第二行BeanFactory beanFactory = new XmlBeanFactory(resource);
这里写图片描述
这里有两步操作,咱们分别分析,首先看第一步对beanFacotry的处理,顺着源码追寻,最终会在AbstractBeanFactory中看到,这里是为了对parentBeanFactory做初始化用于做bean继承关系的支持,但在咱们这个简单的demo中parentBeanFactory最终是Null,所以咱们先不关注
这里写图片描述
然后看第二步,经过一番追寻,最终定位到DefaultBeanDefinitionDocumentReader的doRegisterBeanDefinitions方法,源码如下
这里写图片描述
这个方法很关键,这里会循环递归的对xml文件节点进行解析,目前看来咱们第二步的推测也算合理,
下面看看主要的解析过程parseBeanDefinitions(root, this.delegate);

Spring框架的核心是其控制反转(IoC)容器,对其源码的详细解析有助于更好地理解其工作原理。 Spring IOC容器的本质是个管理POJO对象生命周期的工厂系统,核心实现位于org.springframework.beans和org.springframework.context包。深入分析需要关注BeanFactory和ApplicationContext两大核心接口的源码差异[^3]。 从基本概念上看,传统开发方式在类中手动通过new关键字创建对象,而IoC思想的开发方式是通过IoC容器(Spring框架)来实例化对象,开发者直接从IoC容器获取所需对象,虽失去了创建、管理对象的权力,但无需再考虑对象创建和管理的事务[^4]。 在源码解析方面,有文章深入探讨Spring IoC容器的源码实现,涵盖基本概念、关键接口、bean的生命周期,以及如何解决循环依赖等高级特性。不过有的文章不再过多进行源码步骤介绍,而是提供spring - framework - 5.0.2.RELEASE(中文注释)版本,可解压后用IDEA打开按源码时序图进步分析[^1][2]。 另外,initApplicationEventMulticaster和registerListeners是初始化事件发布器和注册监听器的地方,运用了观察者模式,相关具体源码在《spring源码中设计模式的使用》中有详细讲解[^5]。 ### 示例代码展示 以下为简单示意Spring IOC使用的代码示例: ```java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; class ClassB { public void doSomething() { System.out.println("ClassB is doing something."); } } class ClassA { private ClassB classB; public ClassA(ClassB classB) { this.classB = classB; } public void useClassB() { classB.doSomething(); } } public class Main { public static void main(String[] args) { // 创建Spring IOC容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 从容器中获取对象 ClassA classA = context.getBean(ClassA.class); classA.useClassB(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值