• 『SpringBoot 源码分析』run() 方法执行流程:(2)刷新应用上下文-准备阶段


    『SpringBoot 源码分析』run() 方法执行流程:(2)刷新应用上下文-准备阶段

    • 基于 2.2.9.RELEASE
    • 问题:当方法进行了注释标记之后,springboot 又是怎么注入到容器中并创建类呢?
    1. 首先创建测试主程序
    package com.lagou;
    
    @SpringBootApplication//标注在类上说明这个类是`SpringBoot`的主配置类
    public class SpringBootMytestApplication{
    
    	public static void main(String[] args) {
    		SpringApplication.run(SpringBootMytestApplication.class, args);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 创建测试 Controller
    package com.lagou.controller;
    
    @RestController
    public class TestController {
    
    	@RequestMapping("/test")
    	public String test(){
    		System.out.println("源码环境构建成功...");
    		return "源码环境构建成功";
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    准备阶段

    1. 当准备完成应用上下文环境,以及应用上下文以后,需要为应用上下文做个准备阶段,简单来说其实就是要配置应用上下文,把需要的类装配上
    public class SpringApplication {
    	...
    	public ConfigurableApplicationContext run(String... args) {
    		...
    		try {
    			// 将运行时参数封装
    			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    			// 构造应用上下文环境
    			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
    			// 处理需要忽略的 Bean
    			configureIgnoreBeanInfo(environment);
    			// 打印 banner
    			Banner printedBanner = printBanner(environment);
    			// 刷新应用上下文前的准备阶段
    			context = createApplicationContext();
    			// 实例化 SpringBootExceptionReporter.class,用来支持报告关于启动的错误
    			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
    					new Class[] { ConfigurableApplicationContext.class }, context);
    			// 1. 刷新应用上下文前的准备阶段
    			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
    			...
    		}
    		catch (Throwable ex) {
    			...
    		}
    		...
    	}
    }
    
    • 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
    1. 在对应用上下文进行处理时,主要执行了下面几步的装配
    • 把上下文环境设置到应用上下文中
    • 执行容器后置处理
    • 把应用上下文交给 SpringApplication 初始化收集的 org.springframework.context.ApplicationContextInitializer 所有实现类进行初始化工作
    • 利用 org.springframework.boot.context.event.EventPublishingRunListenerorg.springframework.context.ApplicationListener 发布容器准备好事件
    public class SpringApplication {
    	...
    	// 完成属性设置 bean对象创建
    	private void  prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
    			SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
    		// 1. 设置容器环境
    		context.setEnvironment(environment);
    		// 2. 执行容器后置处理
    		postProcessApplicationContext(context);
    		// 3. 执行一些初始化器
    		applyInitializers(context); 
    		// 4. 向各个监听器发送容器已经准备好的事件
    		listeners.contextPrepared(context);
    		...
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 执行容器后置处理:其实只是往 BeanFactory 添加了基础的转换器
    public class SpringApplication {
    
    	private BeanNameGenerator beanNameGenerator;
    	private ResourceLoader resourceLoader;
    	private boolean addConversionService = true;
    	...
    	protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
    		if (this.beanNameGenerator != null) {
    			context.getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
    					this.beanNameGenerator);
    		}
    		if (this.resourceLoader != null) {
    			if (context instanceof GenericApplicationContext) {
    				((GenericApplicationContext) context).setResourceLoader(this.resourceLoader);
    			}
    			if (context instanceof DefaultResourceLoader) {
    				((DefaultResourceLoader) context).setClassLoader(this.resourceLoader.getClassLoader());
    			}
    		}
    		
    		if (this.addConversionService) { 
    			// 1. 设置了转换器,例如平时能把整数字符串转换为整形,设置转换器
    			context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance());
    		}
    	}
    }
    
    • 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
    • 执行一些初始化器:就是遍历 org.springframework.context.ApplicationContextInitializer 执行 initialize() 方法
    public class SpringApplication {
    	...
    	protected void applyInitializers(ConfigurableApplicationContext context) {
    		for (ApplicationContextInitializer initializer : getInitializers()) {
    			Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
    					ApplicationContextInitializer.class);
    			Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
    			initializer.initialize(context);
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 向各个监听器发送容器已经准备好的事件:就是 org.springframework.boot.context.event.EventPublishingRunListenerorg.springframework.context.ApplicationListener 发布容器准备好事件
    public class SpringApplication {
    	...
    	// 1. 当 ApplicationContext 构建完成时,该方法被调用
    	void contextPrepared(ConfigurableApplicationContext context) {
    		for (SpringApplicationRunListener listener : this.listeners) {
    			listener.contextPrepared(context);
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 发布完监听之后,从上下文中获取 IOC 工厂,并设置允许 bean 定义被覆盖参数
    public class SpringApplication {
    	...
    	// 完成属性设置 bean 对象创建
    	private void  prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
    			SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
    		// 设置容器环境
    		context.setEnvironment(environment);
    		// 执行容器后置处理
    		postProcessApplicationContext(context);
    		// 执行一些初始化器
    		applyInitializers(context); 
    		// 向各个监听器发送容器已经准备好的事件
    		listeners.contextPrepared(context);
    		if (this.logStartupInfo) {
    			logStartupInfo(context.getParent() == null);
    			logStartupProfileInfo(context);
    		}
    		// 1. 获取 IOC 容器
    		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    		// 将 main() 函数中的 args 参数封装成单例 Bean,注册进容器
    		beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
    		if (printedBanner != null) {
    			// 将 printedBanner 也封装成单例,注册进容器
    			beanFactory.registerSingleton("springBootBanner", printedBanner);
    		}
    		// 2. 设置允许 bean 定义被覆盖参数
    		if (beanFactory instanceof DefaultListableBeanFactory) {
    			((DefaultListableBeanFactory) beanFactory)
    					.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    		}
    		...
    	}
    }
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    1. 然后加载启动类,并将启动类注入到容器当中,然后发布容器已加载事件
    public class SpringApplication {
    	...
    	// 完成属性设置 bean 对象创建
    	private void  prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
    			SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
    		// 设置容器环境
    		context.setEnvironment(environment);
    		// 执行容器后置处理
    		postProcessApplicationContext(context);
    		// 执行一些初始化器
    		applyInitializers(context); 
    		// 向各个监听器发送容器已经准备好的事件
    		listeners.contextPrepared(context);
    		if (this.logStartupInfo) {
    			logStartupInfo(context.getParent() == null);
    			logStartupProfileInfo(context);
    		}
    		// 获取 IOC 容器
    		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    		// 将 main() 函数中的 args 参数封装成单例 Bean,注册进容器
    		beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
    		if (printedBanner != null) {
    			// 将 printedBanner 也封装成单例,注册进容器
    			beanFactory.registerSingleton("springBootBanner", printedBanner);
    		}
    		// 设置允许 bean 定义被覆盖参数
    		if (beanFactory instanceof DefaultListableBeanFactory) {
    			((DefaultListableBeanFactory) beanFactory)
    					.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    		}
    		if (this.lazyInitialization) { // 是否需要进行懒加载,这里不是
    			context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
    		}
    		// 1. 加载源,这里拿到的是主类,com.lagou.SpringBootMytestApplication
    		Set<Object> sources = getAllSources();
    		Assert.notEmpty(sources, "Sources must not be empty");
    		// 2. 加载我们的启动类,将启动类注入容器 重点关注
    		load(context, sources.toArray(new Object[0]));// 取出第一个元素,就是主类,要先实例化主类,灌入容器中
    		// 3. 发布容器已加载事件
    		listeners.contextLoaded(context);
    	}
    }
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 其中将启动类注入到容器当中是比较关键的一步,首先先把 ApplicationContext 转换成 BeanDefinitionRegistry,然后创建 bean 定义加载器
    public class SpringApplication {
    	...
    	protected void load(ApplicationContext context, Object[] sources) {
    		if (logger.isDebugEnabled()) {
    			logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
    		}
    		// 2. 创建 BeanDefinitionLoader
    		BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);
    		...
    	}
    	
    	private BeanDefinitionRegistry getBeanDefinitionRegistry(ApplicationContext context) {
    		// 1. 将 ApplicationContext 转换成 BeanDefinitionRegistry
    		if (context instanceof BeanDefinitionRegistry) {
    			return (BeanDefinitionRegistry) context;
    		}
    		if (context instanceof AbstractApplicationContext) {
    			return (BeanDefinitionRegistry) ((AbstractApplicationContext) context).getBeanFactory();
    		}
    		throw new IllegalStateException("Could not locate BeanDefinitionRegistry");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 创建 BeanDefinitionLoader 主要是把 BeanDefinitionRegistry 以及主类的 sources 进行赋值初始化
    public class SpringApplication {
    
    	private final Object[] sources;
    	private final AnnotatedBeanDefinitionReader annotatedReader;
    	private final XmlBeanDefinitionReader xmlReader;
    	private BeanDefinitionReader groovyReader;
    	private final ClassPathBeanDefinitionScanner scanner;
    	private ResourceLoader resourceLoader;
    	...
    	protected BeanDefinitionLoader createBeanDefinitionLoader(BeanDefinitionRegistry registry, Object[] sources) {
    		// 1. 创建 bean 定义加载器
    		return new BeanDefinitionLoader(registry, sources);
    	}
    
    	BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) {
    		// 其中,sources 就是主类 com.lagou.SpringBootMytestApplication
    		Assert.notNull(registry, "Registry must not be null");
    		Assert.notEmpty(sources, "Sources must not be empty");
    		this.sources = sources;
    		// 2. 注解形式的 Bean 定义读取器 比如:@Configuration @Bean @Component @Controller @Service等等
    		this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);
    		// 3. XML 形式的 Bean 定义读取器
    		this.xmlReader = new XmlBeanDefinitionReader(registry);
    		if (isGroovyPresent()) {
    			this.groovyReader = new GroovyBeanDefinitionReader(registry);
    		}
    		// 4. 类路径扫描器
    		this.scanner = new ClassPathBeanDefinitionScanner(registry);
    		// 5. 扫描器添加排除过滤器
    		this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));
    	}
    }
    
    • 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
    • 29
    • 30
    • 31
    • 32
    1. 创建 BeanDefinitionLoader 成功后,就可以开始执行 load(),这里主要是先把主类注册到 IOC 容器中去
    public class SpringApplication {
    
    	private BeanNameGenerator beanNameGenerator;
    	...
    	protected void load(ApplicationContext context, Object[] sources) {
    		if (logger.isDebugEnabled()) {
    			logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
    		}
    		// 创建 BeanDefinitionLoader
    		BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);
    		if (this.beanNameGenerator != null) {
    			loader.setBeanNameGenerator(this.beanNameGenerator);
    		}
    		if (this.resourceLoader != null) {
    			loader.setResourceLoader(this.resourceLoader);
    		}
    		if (this.environment != null) {
    			loader.setEnvironment(this.environment);
    		}
    		// 1. 执行 load()
    		loader.load();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 其中 load() 通过 AnnotatedBeanDefinitionReader 将主类 source 注册进 beanDefinitionMap
    class BeanDefinitionLoader {
    	
    	private final AnnotatedBeanDefinitionReader annotatedReader;
    	...
    	int load() {
    		int count = 0;
    		for (Object source : this.sources) {
    			count += load(source);
    		}
    		return count;
    	}
    	// 根据加载不同类型调用不同的方法
    	private int load(Object source) {
    		Assert.notNull(source, "Source must not be null");
    		// 1. 从 Class 加载
    		if (source instanceof Class<?>) {
    			return load((Class<?>) source);
    		}
    		...
    	}
    
    	private int load(Class<?> source) {
    		// source 就是 class com.lagou.SpringBootMytestApplication
    		if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
    			// Any GroovyLoaders added in beans{} DSL can contribute beans here
    			GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);
    			load(loader);
    		}
    		if (isComponent(source)) { // 判断方法有没有标记 Component 注解
    			// 1. 将启动类的 BeanDefinition 注册进 beanDefinitionMap
    			this.annotatedReader.register(source);
    			return 1;
    		}
    		return 0;
    	}
    }
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 调用 register() 方法时,真正会传到 doRegisterBean() 进行执行。首先会把主类转换成 AnnotatedGenericBeanDefinition,然后获取主类的名称,把名称和 AnnotatedGenericBeanDefinition 封装成 BeanDefinitionHolder 后,注册到上下文中
    public class AnnotatedBeanDefinitionReader {
    	...
    	public void register(Class<?>... componentClasses) {
    		for (Class<?> componentClass : componentClasses) {
    			registerBean(componentClass);
    		}
    	}
    
    	public void registerBean(Class<?> beanClass) {
    		doRegisterBean(beanClass, null, null, null, null);
    	}
    
    	private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
    			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
    			@Nullable BeanDefinitionCustomizer[] customizers) {
    		// 1. 把主类转换成 AnnotatedGenericBeanDefinition,其中 beanClass 为 com.lagou.SpringBootMytestApplication
    		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());
    		// 2. 获取类名 springBootMytestApplication
    		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    
    		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);
    			}
    		}
    		// 3. 封装成 BeanDefinitionHolder 
    		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    		// 4. 注册到容器中		
    		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    	}
    }
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 注册到容器中,简单而言就是调用 BeanDefinitionRegistryBeanDefinitionHolder 的 name 和 AnnotatedGenericBeanDefinition 装配进去
    public abstract class BeanDefinitionReaderUtils {
    	...
        public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
        	// 1. 获取名称 springBootMytestApplication
            String beanName = definitionHolder.getBeanName();
            // 2. 注册到 IOC 容器中
            registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
            String[] aliases = definitionHolder.getAliases();
            if (aliases != null) {
                String[] var4 = aliases;
                int var5 = aliases.length;
    
                for(int var6 = 0; var6 < var5; ++var6) {
                    String alias = var4[var6];
                    registry.registerAlias(beanName, alias);
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 最后会把 name 和 AnnotatedGenericBeanDefinition 存入到 beanDefinitionMap
    public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    	...
        public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
            Assert.hasText(beanName, "Bean name must not be empty");
            Assert.notNull(beanDefinition, "BeanDefinition must not be null");
            // 1. 先校验 beanDefinition 是否合法
            if (beanDefinition instanceof AbstractBeanDefinition) {
                try {
                    ((AbstractBeanDefinition)beanDefinition).validate();
                } catch (BeanDefinitionValidationException var8) {
                    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
                }
            }
    
            BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
            if (existingDefinition != null) {
                if (!this.isAllowBeanDefinitionOverriding()) {
                    throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
                }
    
                if (existingDefinition.getRole() < beanDefinition.getRole()) {
                    if (this.logger.isInfoEnabled()) {
                        this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                    }
                } else if (!beanDefinition.equals(existingDefinition)) {
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                    }
                } else if (this.logger.isTraceEnabled()) {
                    this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                }
    
                this.beanDefinitionMap.put(beanName, beanDefinition);
            } else {
                if (this.hasBeanCreationStarted()) {
                    synchronized(this.beanDefinitionMap) {
                        this.beanDefinitionMap.put(beanName, beanDefinition);
                        List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                        updatedDefinitions.addAll(this.beanDefinitionNames);
                        updatedDefinitions.add(beanName);
                        this.beanDefinitionNames = updatedDefinitions;
                        this.removeManualSingletonName(beanName);
                    }
                } else {
                    // 2. 再把 beanDefinition 放到 beanDefinitionMap 中
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    this.beanDefinitionNames.add(beanName);
                    this.removeManualSingletonName(beanName);
                }
    
                this.frozenBeanDefinitionNames = null;
            }
    
            if (existingDefinition == null && !this.containsSingleton(beanName)) {
                if (this.isConfigurationFrozen()) {
                    this.clearByTypeCache();
                }
            } else {
                this.resetBeanDefinition(beanName);
            }
        }	
    }
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    1. 总结
      在这里插入图片描述
  • 相关阅读:
    WSL2下使用openocd连接外部调试器开发STM32
    C#根据任意不重复的数组产生一个连续的新数组且最短,其中新数组最大数和者最大数+1不在该任意数组中
    【论文阅读】社交网络传播最大化问题-01
    LeetCode 0623.在二叉树中增加一行:DFS / BFS
    【自然语言处理】NLTK库的概念和作用
    仿制 Google Chrome 的恐龙小游戏
    EventBus3 笔记
    git使用小结
    Linux下压缩和解压缩
    Oracle 密码策略详解
  • 原文地址:https://blog.csdn.net/zzz805/article/details/132384038