SpringIOC

几个类
AnnotationConfigServletWebServerApplicationContext

几个定义
ioc容器
beanfactory
factorybean

本文基于SpringBoot2.x版本分析SpringIOC容器的实现原理和工作机制。

一、SpringBoot在启动的时候会初始化一个上下文对象AnnotationConfigServletWebServerApplicationContext。

SpringApplication源码部分

	/**
	 * The class name of application context that will be used by default for web
	 * environments.
	 */
	public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework.boot."
			+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";

    public ConfigurableApplicationContext run(String... args) {

		ConfigurableApplicationContext context = null;
            ...
            context = createApplicationContext();
            ...
            
    }
    
    
    /**
	 * 用来创建ApplicationContext对象的策略方法,根据这个方法,将会支持
	 * 任何显示的设置应用的上下文或者是返回一个默认的AnnotationConfigAppli* cationContext
	 */
	protected ConfigurableApplicationContext createApplicationContext() {
		Class<?> contextClass = this.applicationContextClass;
		if (contextClass == null) {
			try {
				switch (this.webApplicationType) {
				case SERVLET:
					contextClass = Class.forName(DEFAULT_WEB_CONTEXT_CLASS);
					break;
                    ...
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Unable create a default ApplicationContext, "
								+ "please specify an ApplicationContextClass",
						ex);
			}
		}
		return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
	}

分析一下AnnotationConfigServletWebServerApplicationContext
在这里插入图片描述


bean的生命周期
bean的依赖注入

    /** bean定义对象的 Map, keyed是bean的name */
	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

    /**按照注册的顺序,bean定义的名字的集合 */
	private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

	/** 按照注册的顺序,手动注入单例bean的名字的集合List of names of manually registered singletons, in registration order */
	private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);

    /**
    * 
    * 
    */
    @Override
	public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
	    // 调用registerSingleton方法
	    // 先从singletonObjects缓存中去取bean。
	    // 如果取到抛出异常
	    // 如果没有取到,将给到的单例的对象,添加到工厂的缓存中去。
	    
		super.registerSingleton(beanName, singletonObject);
        // 检查Factory的bean创建阶段是否已经开始。
		if (hasBeanCreationStarted()) {
			// Cannot modify startup-time collection elements anymore (for stable iteration)
			synchronized (this.beanDefinitionMap) {
				if (!this.beanDefinitionMap.containsKey(beanName)) {
					Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames.size() + 1);
					updatedSingletons.addAll(this.manualSingletonNames);
					updatedSingletons.add(beanName);
					this.manualSingletonNames = updatedSingletons;
				}
			}
		}
		else {
			// Still in startup registration phase 仍然在开始注册的阶段
			if (!this.beanDefinitionMap.containsKey(beanName)) {
				this.manualSingletonNames.add(beanName);
			}
		}

		clearByTypeCache();
	}

hasBeanCreationStarted()方法,检查Factory的bean创建阶段是否已经开始。

    /** 这些beans的name至少已经被创建过一次 */
	private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));

	protected boolean hasBeanCreationStarted() {
		return !this.alreadyCreated.isEmpty();
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值