1987WEB视界-分享互联网热点话题和事件

您现在的位置是:首页 > WEB开发 > 正文

WEB开发

爱上源码,重学Spring IoC深入

1987web2024-03-26WEB开发45
回答:我们为什么要学习源码?1、知其然知其所以然2、站在巨人的肩膀上,提高自己的编码水平3、应付面试1.1Spring源码阅读小技巧1、类层次藏得太深,不要一

回答: 我们为什么要学习源码? 1、知其然知其所以然 2、站在巨人的肩膀上,提高自己的编码水平 3、应付面试 1.1 Spring源码阅读小技巧 1、类层次藏得太深,不要一个类一个类的去看,遇到方法该进就大胆的进 2、更不要一行一行的去看,看核心点,有些方法并不重要,不要跟它纠缠 3、看不懂的先不看 ...
回答:我们为什么要学习源码?1、知其然知其所以然2、站在巨人的肩膀上,提高自己的编码水平3、应付面试

1.1 Spring源码阅读小技巧

1、类层次藏得太深,不要一个类一个类的去看,遇到方法该进就大胆的进

2、更不要一行一行的去看,看核心点,有些方法并不重要,不要跟它纠缠

3、看不懂的先不看,根据语义和返回值能知道这个方法达到了啥目的即可

4、只看核心接口(下面标注了重点的地方)和核心代码,有些地方也许你使用spring以来都没触发过

5、debug跟步走,源码中给大家标注好了,见到 ”===>“ 就进去

​ 进去之前,下一行打个断点,方便快速回到岔路口

​ 进去之前,可以先点方法看源码,再debug跟进

6、广度优先,而非深度优先。先沿着主流程走,了解大概,再细化某些方法

7、认命。spring里多少万行的代码,一部书都写不完。只能学关键点

阅读源码目的

加深理解spring的bean加载过程

面试吹牛x

江湖传说,spring的类关系是这样的……

1.2 IoC初始化流程与继承关系

引言在看源码之前需要掌握Spring的继承关系和初始化1) IoC容器初始化流程

目标:

1、IoC容器初始化过程中到底都做了哪些事情(宏观目标)

2、IoC容器初始化是如何实例化Bean的(划重点,最终目标)

//没有Spring之前我们是这样的Useruser=newUser();user.xxx();//有了Spring之后我们是这样的<bean id="userService"class="com.spring.test.impl.UserServiceImpl">Useruser=context.getBean("xxx");user.xxx();

IoC流程简化图:

tips:

下面的流转记不住没有关系

在剖析源码的整个过程中,我们一直会拿着这个图和源码对照

初始化:

1、容器环境的初始化

2、Bean工厂的初始化(IoC容器启动首先会销毁旧工厂、旧Bean、创建新的工厂)

读取与定义

读取:通过BeanDefinitonReader读取我们项目中的配置(application.xml)

定义:通过解析xml文件内容,将里面的Bean解析成BeanDefinition(未实例化、未初始化)

实例化与销毁

Bean实例化、初始化(注入)

销毁缓存等

扩展点

事件与多播、后置处理器

复杂的流程关键点:

重点总结:

1、工厂初始化过程

2、解析xml到BeanDefinition,放到map

3、调用后置处理器

4、从map取出进行实例化( ctor.newInstance)

5、实例化后放到一级缓存(工厂)

2) 容器与工厂继承关系

tips:

别紧张,下面的继承记不住没有关系

关注颜色标注的几个就可以

目标:简单理解ioC容器继承关系

继承关系理解:

1、ClassPathXmlApplicationContext最终还是到了 ApplicationContext 接口,同样的,我们也可以使用绿颜色的 FileSystemXmlApplicationContext 和 AnnotationConfigApplicationContext 这两个类完成容器初始化的工作

2、FileSystemXmlApplicationContext的构造函数需要一个 xml 配置文件在系统中的路径,其他和 ClassPathXmlApplicationContext 基本上一样

3、AnnotationConfigApplicationContext的构造函数扫描classpath中相关注解的类,主流程一样

课程中我们以最经典的 classpathXml 为例。

Bean工厂继承关系

目标:

ApplicationContext 和 BeanFactory 啥关系?

BeanFactory 和 FactoryBean呢?

总结:

别害怕,上面的继承关系不用刻意去记住它

其实接触到的就最下面这个!

1.3 开始搭建测试项目

四步:

1、新建测试module项目

首先我们在 Spring 源码项目中新增一个测试项目,点击 New -> Module... 创建一个 Gradle 的 Java 项目

2、详细信息

3、设置gradle

4、完善信息

在 build.gradle 中添加对 Spring 源码的依赖:

compile(project(:spring-context))

spring-context 会自动将 spring-core、spring-beans、spring-aop、spring-expression 这几个基础 jar 包带进来。

接着,我们需要在项目中创建一个 bean 和配置文件(application.xml)及启动文件(Main.java)

接口如下:

packagecom.spring.test.service;publicinterfaceUserService{publicStringgetName();}

实现类

packagecom.spring.test.impl;importcom.spring.test.service.UserService;publicclassUserServiceImplimplementsUserService{@OverridepublicStringgetName(){return"Hello World";}}

Main代码如下

publicclassTest{publicstaticvoidmain(String[]args){ApplicationContextcontext=newClassPathXmlApplicationContext("classpath*:application.xml");UserServiceuserService=context.getBean(UserService.class);System.out.println(userService);// 这句将输出: hello worldSystem.out.println(userService.getName());}}

配置文件 application.xml(在 resources 中)配置如下:

id="applicationContextListener"class="com.spring.test.pattern.observer.ApplicationContextListener"/> id="applicationContextListenerTwo"class="com.spring.test.pattern.observer.ApplicationContextListenerTwo"/> id="applicationContextListenerPubisher"class="com.spring.test.pattern.observer.ApplicationContextListenerPubisher"/>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->

测试

//总结 :使用bean工厂发布和使用多播器效果是一样的publicclassTest{publicstaticvoidmain(String[]args){ApplicationContextcontext=newClassPathXmlApplicationContext("classpath*:application.xml");//***************使用spring的多播器发布**********************ApplicationEventMulticasterapplicationEventMulticaster=(ApplicationEventMulticaster)context.getBean("applicationEventMulticaster");applicationEventMulticaster.multicastEvent(newMessageSourceEvent("测试..."));//***************使用BeanFactory的publishEvent发布*********************// ApplicationContextListenerPubisher myPubisher = (ApplicationContextListenerPubisher)//context.getBean("applicationContextListenerPubisher");//myPubisher.publishEvent(new MessageSourceEvent("测试..."));}}

多播发布

工厂发布

总结:

​ 1、spring的事件驱动模型使用的是 观察者模式

2、通过ApplicationEvent抽象类和ApplicationListener接口,可以实现事件处理

3、ApplicationEventMulticaster事件广播器实现了监听器的注册,一般不需要我们实现,只需要显示的调用 applicationcontext.publisherEvent方法即可

​ 4、使用bean工厂发布和使用多播器效果是一样的

本文由传智教育博学谷教研团队发布。

如果本文对您有帮助,欢迎关注和点赞;如果您有任何建议也可留言评论或私信,您的支持是我坚持创作的动力。

转载请注明出处!

声明:本站所有文章,如无特殊说明或标注,均为爬虫抓取以及网友投稿,版权归原作者所有。