关于Spring启动时Context加载源码分析
前言 本文主要给大家介绍了关于Spring启动时Context加载的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 测试源码下载test-annotation.zip 有如下的代码 @Component public class HelloWorldService { @Value("${name:World}") private String name; public String getHelloMessage() { return "Hello " + this.name; } } @Configuration public 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(); } }
上下文的加载主要发生在
为@Configuration类中@Bean标注的方法生成BeanDefinition对象详细过程如下 步骤1、找到合适的BeanDefinitionRegistryPostProcessor处理器 org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors() { ... //获取适用的BeanDefinitionRegistryPostProcessor bean名称 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class,true,false); ... //根据beanName获取PostProcessor, 处理@Configuration标注类的beanName为 //org.springframework.context.annotation.internalConfigurationAnnotationProcessor //实现为org.springframework.context.annotation.ConfigurationClassPostProcessor ConfigurationClassPostProcessor postProcessor =beanFactory.getBean(postProcessorNames[0],BeanDefinitionRegistryPostProcessor.class) } 步骤2、为@Configuration产生ConfigurationClass对象 //使用ConfigurationClassParser解析@Configuration标注的类, //每一个@Configuration标注的类产生一个ConfigurationClass对象, // //@Bean标注的方法使用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标注的方法产生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的实例 this.registry.registerBeanDefinition(beanName,beanDefToRegister); } 此过程的调用栈: 根据BeanDefinition生成实例过程的调用栈: 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对编程小技巧的支持。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |