关于Spring启动时Context加载源码分析

网友投稿 281 2023-02-27


关于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();

}

}

HelloWorldService.getHelloMessage方法简单的返回name的值, BootStrap.main方法中使用AnnotationConfigApplicationContext 构造一个上下文对象, 为了演示的方便, 显示的声明了DefaultListableBeanFactory和InstantiationStrategMWqkTrUeFSy实例。通过applicationContext.getBean()获取bean的引用,并调用 service.getHelloMessage() 方法。

上下文的加载主要发生在applicationContext.register方法和applicationContext.refresh方法中,

applicationContext.register方法的作用是为参数(使用@Configuration注解的class)生成BeanDefinition 对象并调用DefaultListableBeanFactory.registerBeanDefinition将BeanDefinition注册到DefaultListableBeanFactory中。

applicationContext.refresh()的功能要更多,主要功能一的是调用PostProcessor为@Configuration类中的@Bean标注的方法生成对应的BeanDefinition对象,并注册到DefaultListableBeanFactory中,功能二是遍历DefaultListableBeanFactory中BeanDefinition, 产生真正的对象。

为@Configuration类中@Bean标注的方法生成BeanDefinition对象详细过程如下

步骤1、找到合适的BeanDefinitionRegistryPostProcessor处理器

org.springframework.context.support.PMWqkTrUeFSostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors() {

...

//获取适用的BeanDefinitionRegistryPostProcessor bean名称

String[] postProcessorNames =

beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

...

//根据beanName获取PostProcessor, 处理@Configuration标注类的beanName为

//org.springframework.context.annotation.internalConfigurationAnnotationProcessor

//实现为org.springframework.context.annotation.Configurathttp://ionClassPostProcessor

ConfigurationClassPostProcessor postProcessor =beanFactory.getBean(postProcessorNames[0], BeanDefinitionRegistryPostProcessor.class)

}

步骤2、为@Configuration产生ConfigurationClass对象

//使用ConfigurationClassParser解析@Configuration标注的类,

//每一个@Configuration标注的类产生一个ConfigurationClass对象,

//ConfigurationClass.getBeanMethods()能获得该类中所有使用@Bean标注的方法,

//@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生成实例过程的调用栈:

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:http接口测试
下一篇:api文档工具
相关文章

 发表评论

暂时没有评论,来抢沙发吧~