<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
인데 무엇을 저장하나요? 하위 클래스 AbstractBeanDefinition
BeanDefinition
那么他存储了什么东西呢?我们看一下它的子类AbstractBeanDefinition
里面定义这类似与这样的属性值,当然作者做截取了少数属性,它里面的属性远远比这多得多,它的目的就是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工厂有了」
「然后再自己的空构造方法里面有初始化了读取器!」
那我们继续回到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
,这样才能获取后续咱们要解析的包,当然这个方法不光解析了扫描的包,还解析了其他东西,本文不做讲解!
好了,再往下走我们就知道了我们即将要扫描那些包下的类,让他变成bean,那么我们继续向下走,走到refresh();
AnnotationConfigApplicationContext
를 입력하면 초기화되지 않은 것을 확인할 수 있습니다. 우리 모두 알고 있듯이 클래스가 다시 초기화되면 상위 클래스의 생성자가 먼저 로드되므로 해당 상위 클래스 GenericApplicationContext
를 살펴봐야 합니다.rrreee
예상대로, 그것은 상위 클래스입니다. Bean 팩토리가 내부에 생성되고 팩토리가 거기에 있습니다. 계속해서AnnotationConfigApplicationContext
로 돌아가서 살펴보겠습니다. 이것이 호출되었음을 나타내는 this()를 호출하는 것을 발견합니다. 자체 빈 생성자이므로 입력합니다. 살펴보세요: "그러면 비어있는 리더가 생성 방법으로 초기화됩니다! 》
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 등록을 모든8) .initaapplicationEventMulticaster () ❝BeanFactoryPostProcessors
로 스캔하는 것이라고 추측할 수 있습니다. >, 첫 번째 확장 지점이 여기에 나타납니다.BeanFactoryPostProcessors
를 사용자 정의할 때 콜백 타이밍은 Spring이 모든BeanDefinition
을 읽는 시점입니다. 독자는 특정 사용 방법에 대해 Baidu를 참조할 수 있습니다. *beanPostProcessor
인터페이스의 확장점을 사용해 본 적이 있는지 궁금하십니까? 물론 이 방법으로 Spring 팩토리에 등록되지만, 등록만 되고 실행되지는 않는다는 점에 유의하세요! 기억은 실행되지 않습니다!❞ initMessageSource(); 리소스 초기화
❞
BeanFactoryPostProcessors
,这里出现了第一个扩展点,自定义实现BeanFactoryPostProcessors
的时候,他的回调时机是在Spring读取了全部的BeanDefinition
之后调用的,具体的使用方法读者自行百度!
❝这里是注册bean的后置处理器 也就是 beanPostProcessor 的实现 还有自己内置的处理器 注意这里并没有调用该处理器,只是将胡处理器注册进来bean工厂! 不知道大家使用过
❞beanPostProcessor
接口这个扩展点吗?他就是再这个方法里面被注册到Spring工厂里面的,当然注意一下,他只是注册进去了,并没有执行!记住并没有执行!
❝怎么说呢,这个方法作者并不准备深究,因为他和本篇文章的意图相违背,他的目的是做一个国际化操作也就是 i18n的资源初始化
❞
❝Spring为我们提供了对于事件编程的封装,一般来说事件分为三个角色,
❞事件广播器
(发布事件),事件监听器
(监听事件),事件源
(具体的事件信息)三个角色,这个方法的目的就是初始化事件的广播器!
❝这里又是一个扩展点,内部的方法为空,Spring并没有实现它,供调用者实现!
❞
❝注册Spring的事件监听器,上面已经说过了,这里是初始化并且注册事件监听器
❞
❝这个方法是一个重点,他是为了实例化所有剩余的(非延迟初始化)单例。我们所说的bean的实例化,注入,解决循环依赖,回调
beanPostProcessor
❝ 여기에 또 다른 확장 지점이 있습니다. Spring은 이를 인식하지 못하지만 공급자는 실현됩니다. . 10).Registerlistener(); ❝ 등록된 Spring 이벤트 모니터입니다. 11) FinishbeanFactoryinitialization(BeanFactory); 중요한 점은 나머지(지연 초기화가 아닌) 싱글톤을 모두 인스턴스화하는 것입니다. Bean 인스턴스화, 주입, 순환 종속성 해결,적 적 적 적 적 적 적 적 은 일반적으로 이벤트 프로그래밍을 위해 캡슐화됩니다. 이벤트 게시),
이벤트 리스너
(이벤트 수신),이벤트 소스
(특정 이벤트 정보) 세 가지 역할로 나누어집니다. 이 메서드의 목적은 초기화하는 것입니다. 이벤트 방송인! 9).
beanPostProcessor
콜백 및 기타 작업이 모두 여기에 구현됩니다! ❞ ..finishRefresh(),. 봄 내장 이벤트 ❞ 🎜🎜🎜🎜🎜🎜위 내용은 Java의 Spring 소스 코드 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!