前言
本文主要给大家介绍了关于Spring启动时Context加载的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。
测试源码下载test-annotation.zip
有如下的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
@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和InstantiationStrategy实例。通过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处理器
1
2
3
4
5
6
7
8
9
10
11
|
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对象,
//ConfigurationClass.getBeanMethods()
能获得该类中所有使用@Bean标注的方法,
//@Bean标注的方法使用BeanMethod对象表示
1
2
3
4
5
6
7
8
|
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中
1
2
3
4
5
6
7
|
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生成实例过程的调用栈:
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:http://www.javacoder.cn/?p=1174