使用spring的日常开发过程就是声明bean到容器,再注入给其他bean,大家想过没有,容器到底是什么东东,spring如何实现的,今天我们就来看下spring的容器原理。容器是spring抽象出来的接口BeanFactory,声明了一系列操作bean的方法,默认实现为DefaultListableBeanFactory
。spring启动过程中创建应用上下文时,会以反射方式构造应用上下文实例对象AnnotationConfigServletWebServerApplicationContext
,此时会在继承的父类GenericApplicationContext
生成容器对象DefaultListableBeanFactory
。
public ConfigurableApplicationContext run(String... args) {
......context = createApplicationContext();
......}protected ConfigurableApplicationContext createApplicationContext() {
......switch (this.webApplicationType) {case SERVLET:contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);break;
......return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);} public GenericApplicationContext() {this.beanFactory = new DefaultListableBeanFactory();}
接下来是容器初始化阶段,还记得之前spring启动时从spring.factories中读取的初始化器吗,现在排上用场了,其中
SharedMetadataReaderFactoryContextInitializer
会添加CachingMetadataReaderFactoryPostProcessor
,ConfigurationWarningsApplicationContextInitializer
会添加ConfigurationWarningsPostProcessor
,接下来一步非常重要,就是往容器中注册main类的bean定义,注册后后续的才会按main类上的注解扫描代码中定义的bean。
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,@Nullable BeanDefinitionCustomizer[] customizers) {AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}abd.setInstanceSupplier(supplier);ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);abd.setScope(scopeMetadata.getScopeName());//生成bean的nameString beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));//处理@Lazy、@Primary、@DependsOn、@Role、@Description注解AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {if (Primary.class == qualifier) {abd.setPrimary(true);}else if (Lazy.class == qualifier) {abd.setLazyInit(true);}else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}if (customizers != null) {for (BeanDefinitionCustomizer customizer : customizers) {customizer.customize(abd);}}//注册main类的bean定义到容器中BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}
刷新容器时会配置容器,然后在容器的后置处理器中处理,过程如下:
- 调用spring内置的BeanDefinitionRegistryPostProcessor
- 优化调用PriorityOrdered的BeanDefinitionRegistryPostProcessor,扫描bean的ConfigurationClassPostProcessor就是此时调用。
- 再调用Ordered的BeanDefinitionRegistryPostProcessor
- 最后调用普通的BeanDefinitionRegistryPostProcessor接口,直到容器中所有的BeanDefinitionRegistryPostProcessor都调用完
public void refresh() throws BeansException, IllegalStateException {
......//获取容器ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//配置容器,添加环境、Java属性、环境变量prepareBeanFactory(beanFactory);try {// 增强处理,暂不关注postProcessBeanFactory(beanFactory);// 重点:调用容器的后置处理器接口invokeBeanFactoryPostProcessors(beanFactory);
......}}public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {// Invoke BeanDefinitionRegistryPostProcessors first, if any.Set<String> processedBeans = new HashSet<>();//分BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor两种类型接口调用if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;//先处理内部的BeanDefinitionRegistryPostProcessorregistryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);}else {regularPostProcessors.add(postProcessor);}}//PriorityOrdered类的BeanDefinitionRegistryPostProcessor优先级最高List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// Ordered次之postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// 普通的BeanDefinitionRegistryPostProcessor处理,如果新增了BeanDefinitionRegistryPostProcessor则继续调用,直到全部调用完boolean reiterate = true;while (reiterate) {reiterate = false;postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);reiterate = true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();}// Now, invoke the postProcessBeanFactory callback of all processors handled so far.invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}......}
进入到扫描bean的流程已经提前看过了,现在就豁然开朗了,知道扫描bean的过程了吧。总结下,spring中的容器本质为声明了操作bean方法的BeanFactory接口的实现,然后从spring上下文中获取相关配置,扫描到我们代码中声明的bean后由容器托管。有不对的地方请大神指出,欢迎大家一起讨论交流,共同进步,更多请关注微信公众号 葡萄开源