>  기사  >  Java  >  Java의 Spring 소스 코드 분석

Java의 Spring 소스 코드 분석

WBOY
WBOY앞으로
2023-04-30 23:13:05826검색

소스 코드 분석

1. 초기 준비

<code>/**<br> * spring debug<br> * @author huangfu<br> */<br>public class SpringDebug {<br>public static void main(String[] args) {<br>		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(SpringDebugConfig.class);<br>	}<br>}<br></code>

위 코드 줄은 Spring을 사용해 본 사람이라면 누구나 매우 익숙할 것으로 추정됩니다. 그렇지 않다면 먼저 사용법을 배우는 것이 좋습니다. , 그리고 몇 가지 소스 코드를 탐구합니다. 기본 논리!

Bean을 단계별로 인스턴스화하고, Bean을 인수한 후, 다양한 Life Cycle 클래스를 실행하는 방법을 살펴보겠습니다! 먼저 추측해 보겠습니다. Spring이 이러한 Bean을 읽을 때 Bean에 대한 정보는 특정 엔터티에 저장되어야 합니다. 이 클래스는 BeanDefinition인데 무엇을 저장하나요? 하위 클래스 AbstractBeanDefinitionBeanDefinition那么他存储了什么东西呢?我们看一下它的子类AbstractBeanDefinition

Java의 Spring 소스 코드 분석        

里面定义这类似与这样的属性值,当然作者做截取了少数属性,它里面的属性远远比这多得多,它的目的就是bean实例化的时候,需要的数据不需要再通过自己去反射获取,而是再Spring初始化的时候全部读取,需要的时候从这里面拿就行,了解了bd的概念之后,我们是否疑惑?他读取之后存放在哪里呢?答案是存放再beanFactory里面,所以Spring初始化的时候肯定会先实现一个bean工厂!进入到AnnotationConfigApplicationContext里面,你会发下并没有初始化,在那初始化呢?众所周知,一个类再初始化的时候会先加载父类的构造函数,所以我们需要去看一下它的父类GenericApplicationContext:

<code>public GenericApplicationContext() {<br>    //初始化bean的工厂<br>    this.beanFactory = new DefaultListableBeanFactory();<br>}</code>     

果然不出我所料,它再父类里面创建了bean工厂,工厂有了,我们继续回到AnnotationConfigApplicationContext里面往下看:发现它调用了一个this(),说明它调用了自己的空构造方法,所以,我们进入看一下:

<code>public AnnotationConfigApplicationContext() {<br>    //初始化读取器<br>    this.reader = new AnnotatedBeanDefinitionReader(this);<br>    //初始化扫描器<br>    this.scanner = new ClassPathBeanDefinitionScanner(this);<br>}</code>   

「至此我们就可以看对照上面那幅图:初始化的时候bean工厂有了」

Java의 Spring 소스 코드 분석        

「然后再自己的空构造方法里面有初始化了读取器!」

Java의 Spring 소스 코드 분석        

那我们继续回到AnnotationConfigApplicationContext构造方法里面:

<code>   /**<br>	 * 创建一个新的AnnotationConfigApplicationContext,从给定的带注释的类派生bean定义<br>	 * 并自动刷新上下文。<br>	 * @param annotatedClasses one or more annotated classes,<br>	 * e.g. {@link Configuration @Configuration} classes<br>	 */<br>public AnnotationConfigApplicationContext(Class>... annotatedClasses) {<br>//读取Spring内置的几个的class文件转换为bd  然后初始化bean工厂<br>this();<br>//这一步就是将配置类Config进行了注册并解析bd<br>		register(annotatedClasses);<br>//这一步是核心,Spring的理解全在这一步,这一步理解了也就可以说将Spring理解了70%<br>//内部做一系列的操作如调用bean工厂的后置处理器   实例化类  调用 后置处理器的前置处理   初始化类  调用后置处理器的后置处理 注册事件监听等操作<br>//完成一个类从class文件变为bean的生命周期<br>		refresh();<br>	}</code>     

下一步是调用register方法,干什么呢?试想一下,有时候我们的自动扫描配置是通过注解@ComponentScan("com.service")来配置的,这个类一般在哪?对了,一般实在配置类中的!

<code>@Configuration<br>@ComponentScan("com.service")<br>public class SpringDebugConfig {}</code>     

为了能够知道,我们要扫描那些包下的类,我们就必须先去解析配置类的BeanDefinition,这样才能获取后续咱们要解析的包,当然这个方法不光解析了扫描的包,还解析了其他东西,本文不做讲解!     

2.核心功能

好了,再往下走我们就知道了我们即将要扫描那些包下的类,让他变成bean,那么我们继续向下走,走到refresh();

Spring source code analyze in java

이와 비슷한 속성값을 정의하고 있습니다. 물론 작성자가 몇 가지 속성을 가로채서 훨씬 더 많은 속성이 있습니다. 그 목적은 Bean이 인스턴스화될 때 필요한 데이터를 직접 가져올 필요가 없으며 대신 Spring 초기화 중에 여기에서 가져올 수 있다는 것입니다. 필요합니다. bd의 개념을 이해하십시오. 그러면 우리는 궁금합니까? 읽은 후 어디에 저장되나요? 대답은 그것을 beanFactory에 저장하는 것이므로 Spring은 초기화할 때 반드시 먼저 bean 팩토리를 구현할 것입니다! AnnotationConfigApplicationContext를 입력하면 초기화되지 않은 것을 확인할 수 있습니다. 우리 모두 알고 있듯이 클래스가 다시 초기화되면 상위 클래스의 생성자가 먼저 로드되므로 해당 상위 클래스 GenericApplicationContext를 살펴봐야 합니다.

rrreee

예상대로, 그것은 상위 클래스입니다. Bean 팩토리가 내부에 생성되고 팩토리가 거기에 있습니다. 계속해서 AnnotationConfigApplicationContext로 돌아가서 살펴보겠습니다. 이것이 호출되었음을 나타내는 this()를 호출하는 것을 발견합니다. 자체 빈 생성자이므로 입력합니다. 살펴보세요:
rrreee
"이 시점에서 위 그림을 볼 수 있습니다. 초기화 중에 Bean 팩토리가 있습니다."
Java의 Spring 소스 코드 분석

"그러면 비어있는 리더가 생성 방법으로 초기화됩니다! 》

2. 핵심 기능

좋습니다. 더 나아가면 해당 패키지 아래의 클래스를 스캔하여 Bean으로 변환할 것임을 알게 됩니다. 그런 다음 계속해서 refresh()로 이동합니다. ;이 방법은 전체 Springbean 초기화의 핵심 방법입니다. 이를 이해하면 Spring의 인스턴스화, 콜백 및 기타 문제를 이해할 수 있습니다.
메소드가 수행하는 기능을 분석하기 위한 첫 번째 방법은 다음과 같습니다.
1) prepareRefresh();

❝ 🎜다음은 주로 여러 속성에 대한 Bean 팩토리를 새로 고치기 전 일련의 할당 작업입니다. 앞서 생성한 Spring 팩토리가 비어 있는 경우, 이 방법은 그를 위해 일련의 초기화 값 작업을 수행하는 것입니다!                                                    ' ' s ' s 1 그래서 너무 너무 너무 너무 너무 너무 너무 너무 너무 너무 너무 너무 너무 so so so so so so so so so so so so... 한 번만 새로 고쳐지고 오류는 여러 번 보고됩니다. 단계가 xml이면 새 팩토리가 반환됩니다. Bean 컨테이너를 생성하고 반환하려면 일반적으로 BeanPostProcessor라고 하는 beanFactory에 자체 내장 Bean 후처리기 중 일부를 등록하세요.❞                                                                     postProcessBeanFactory(beanFactory); 빈 메소드는 무엇을 의미하나요? 이는 Spring 개발자가 호출자가 사용자 정의 확장을 사용하기를 원한다는 것을 의미합니다! Ni i). InvokebeanFactoryPostProcessors (Beanfactory);
실제로 이름을 믿으면 대부분의 독자는 그의 목적이 구성되지 않은 클래스의 BD 등록을 모든 BeanFactoryPostProcessors로 스캔하는 것이라고 추측할 수 있습니다. >, 첫 번째 확장 지점이 여기에 나타납니다. BeanFactoryPostProcessors를 사용자 정의할 때 콜백 타이밍은 Spring이 모든 BeanDefinition을 읽는 시점입니다. 독자는 특정 사용 방법에 대해 Baidu를 참조할 수 있습니다. * beanPostProcessor 인터페이스의 확장점을 사용해 본 적이 있는지 궁금하십니까? 물론 이 방법으로 Spring 팩토리에 등록되지만, 등록만 되고 실행되지는 않는다는 점에 유의하세요! 기억은 실행되지 않습니다!

❞                                                    initMessageSource(); 리소스 초기화

8) .initaapplicationEventMulticaster ()

BeanFactoryPostProcessors,这里出现了第一个扩展点,自定义实现BeanFactoryPostProcessors的时候,他的回调时机是在Spring读取了全部的BeanDefinition之后调用的,具体的使用方法读者自行百度!

❞             
6). registerBeanPostProcessors(beanFactory);
❝      

这里是注册bean的后置处理器 也就是  beanPostProcessor 的实现 还有自己内置的处理器  注意这里并没有调用该处理器,只是将胡处理器注册进来bean工厂! 不知道大家使用过beanPostProcessor接口这个扩展点吗?他就是再这个方法里面被注册到Spring工厂里面的,当然注意一下,他只是注册进去了,并没有执行!记住并没有执行!

❞            
7). initMessageSource();
❝      

怎么说呢,这个方法作者并不准备深究,因为他和本篇文章的意图相违背,他的目的是做一个国际化操作也就是 i18n的资源初始化

❞             
8).initApplicationEventMulticaster();
❝      

Spring为我们提供了对于事件编程的封装,一般来说事件分为三个角色,事件广播器(发布事件),事件监听器(监听事件),事件源(具体的事件信息)三个角色,这个方法的目的就是初始化事件的广播器!

❞             
9). onRefresh();
❝      

这里又是一个扩展点,内部的方法为空,Spring并没有实现它,供调用者实现!

❞             
10). registerListeners();
❝      

注册Spring的事件监听器,上面已经说过了,这里是初始化并且注册事件监听器

❞             
11). finishBeanFactoryInitialization(beanFactory);
❝      

这个方法是一个重点,他是为了实例化所有剩余的(非延迟初始化)单例。我们所说的bean的实例化,注入,解决循环依赖,回调beanPostProcessor

적 적 적 적 적 적 적 적 은 일반적으로 이벤트 프로그래밍을 위해 캡슐화됩니다. 이벤트 게시), 이벤트 리스너(이벤트 수신), 이벤트 소스(특정 이벤트 정보) 세 가지 역할로 나누어집니다. 이 메서드의 목적은 초기화하는 것입니다. 이벤트 방송인! 9).

❝ 여기에 또 다른 확장 지점이 있습니다. Spring은 이를 인식하지 못하지만 공급자는 실현됩니다. . 10).Registerlistener(); ❝ 등록된 Spring 이벤트 모니터입니다. 11) FinishbeanFactoryinitialization(BeanFactory); 중요한 점은 나머지(지연 초기화가 아닌) 싱글톤을 모두 인스턴스화하는 것입니다. Bean 인스턴스화, 주입, 순환 종속성 해결, beanPostProcessor 콜백 및 기타 작업이 모두 여기에 구현됩니다! ❞                                                  ..finishRefresh(),. 봄 내장 이벤트 ❞ 🎜🎜🎜🎜🎜🎜

위 내용은 Java의 Spring 소스 코드 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제