国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > Java > 正文

關(guān)于Spring啟動(dòng)時(shí)Context加載源碼分析

2024-07-13 10:16:40
字體:
供稿:網(wǎng)友

前言

本文主要給大家介紹了關(guān)于Spring啟動(dòng)時(shí)Context加載的相關(guān)內(nèi)容,分享出來供大家參考學(xué)習(xí),下面話不多說了,來一起看看詳細(xì)的介紹吧。

測試源碼下載test-annotation.zip

有如下的代碼

@Componentpublic class HelloWorldService { @Value("${name:World}") private String name; public String getHelloMessage() { return "Hello " + this.name; }}@Configurationpublic class BootStrap { @Bean public static HelloWorldService helloService() { return new HelloWorldService(); } public static void main(String[] args) { InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy(); DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); beanFactory.setInstantiationStrategy(instantiationStrategy); AnnotationConfigApplicationContext applicationContext =  new AnnotationConfigApplicationContext(beanFactory); applicationContext.register(BootStrap.class); applicationContext.refresh(); HelloWorldService service = applicationContext.getBean(HelloWorldService.class); System.out.println(service.getHelloMessage()); applicationContext.close(); }}

HelloWorldService.getHelloMessage方法簡單的返回name的值, BootStrap.main方法中使用AnnotationConfigApplicationContext 構(gòu)造一個(gè)上下文對象, 為了演示的方便, 顯示的聲明了DefaultListableBeanFactory和InstantiationStrategy實(shí)例。通過applicationContext.getBean()獲取bean的引用,并調(diào)用 service.getHelloMessage() 方法。

上下文的加載主要發(fā)生在applicationContext.register方法和applicationContext.refresh方法中,
applicationContext.register方法的作用是為參數(shù)(使用@Configuration注解的class)生成BeanDefinition 對象并調(diào)用DefaultListableBeanFactory.registerBeanDefinition將BeanDefinition注冊到DefaultListableBeanFactory中。

applicationContext.refresh()的功能要更多,主要功能一的是調(diào)用PostProcessor為@Configuration類中的@Bean標(biāo)注的方法生成對應(yīng)的BeanDefinition對象,并注冊到DefaultListableBeanFactory中,功能二是遍歷DefaultListableBeanFactory中BeanDefinition, 產(chǎn)生真正的對象。

為@Configuration類中@Bean標(biāo)注的方法生成BeanDefinition對象詳細(xì)過程如下

步驟1、找到合適的BeanDefinitionRegistryPostProcessor處理器

org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors() { ... //獲取適用的BeanDefinitionRegistryPostProcessor bean名稱 String[] postProcessorNames =  beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); ... //根據(jù)beanName獲取PostProcessor, 處理@Configuration標(biāo)注類的beanName為 //org.springframework.context.annotation.internalConfigurationAnnotationProcessor  //實(shí)現(xiàn)為org.springframework.context.annotation.ConfigurationClassPostProcessor ConfigurationClassPostProcessor postProcessor =beanFactory.getBean(postProcessorNames[0], BeanDefinitionRegistryPostProcessor.class)}

步驟2、為@Configuration產(chǎn)生ConfigurationClass對象

//使用ConfigurationClassParser解析@Configuration標(biāo)注的類,

//每一個(gè)@Configuration標(biāo)注的類產(chǎn)生一個(gè)ConfigurationClass對象,

//ConfigurationClass.getBeanMethods()能獲得該類中所有使用@Bean標(biāo)注的方法,

//@Bean標(biāo)注的方法使用BeanMethod對象表示

org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(BeanDefinitionRegistry registry) { ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); parser.parse(configCandidates); parser.validate(); this.reader.loadBeanDefinitions(parser.getConfigurationClasses());}

步驟3、@Bean標(biāo)注的方法產(chǎn)生BeanDefinition并注入到DefaultListableBeanFactory中

org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass); beanDef.setBeanClassName(configClass.getMetadata().getClassName()); beanDef.setFactoryMethodName(metadata.getMethodName()); //registry 是DefaultListableBeanFactory的實(shí)例 this.registry.registerBeanDefinition(beanName, beanDefToRegister);}

此過程的調(diào)用棧:

spring,context,源碼,加載context

根據(jù)BeanDefinition生成實(shí)例過程的調(diào)用棧:

spring,context,源碼,加載context

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網(wǎng)的支持。


注:相關(guān)教程知識閱讀請移步到JAVA教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 云和县| 三门峡市| 新乡县| 顺平县| 友谊县| 阳江市| 四会市| 上饶县| 松桃| 郯城县| 南陵县| 仲巴县| 常熟市| 阜阳市| 阳信县| 方山县| 天祝| 旬邑县| 中山市| 平乡县| 南宁市| 腾冲县| 七台河市| 博罗县| 明水县| 偃师市| 邓州市| 利川市| 广南县| 云浮市| 即墨市| 眉山市| 邳州市| 上杭县| 邹平县| 遵化市| 罗田县| 邻水| 合阳县| 英吉沙县| 阿拉善右旗|