Spring 上下文的加载

栏目: Java · 发布时间: 6年前

内容简介:Spring 上下文的加载

测试源码下载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和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, 产生真正的对象。

本文由javacoder.cn整理,转载注明出处

为@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对象,

//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);
}

此过程的调用栈:

Spring 上下文的加载

根据BeanDefinition生成实例过程的调用栈:

Spring 上下文的加载

Posted in:spring practise


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

拆掉互联网那堵墙

拆掉互联网那堵墙

庄良基 / 经济日报出版社 / 2014-6 / 25.80

都在说道互联网、说道电子商务、说道移动APP、说道微信、说道互联网金融......我们该如何认识互联网?中小微企业该如何借力互联网?互联网很神秘吗?很高深莫测吗? 其实互联网并没有什么神秘的,也没有什么高深莫测的!互联网无非是人类发明的工具而已,既然是工具,我们就一定可以驾驭和使用它。既然可以双重使用,就理当让所有有人都容易掌握并轻松驾驭。 互联网离我们很远吗?互联网界的成功故事都是那......一起来看看 《拆掉互联网那堵墙》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

随机密码生成器
随机密码生成器

多种字符组合密码