zoukankan      html  css  js  c++  java
  • BeanDefinition注册逻辑解析

    //调用:BeanDefinitionReaderUtils.registerBeanDefinition
    //最终实现:org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
    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");
    
    		if (beanDefinition instanceof AbstractBeanDefinition) {
    			try {
    				// 校验,注册前的最后一次校验,这里主要对methodOverrides 属性进行校验
    				// 看定义的对应的类和和方法是否存在
    				((AbstractBeanDefinition) beanDefinition).validate();
    			}
    			catch (BeanDefinitionValidationException ex) {
    				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
    						"Validation of bean definition failed", ex);
    			}
    		}
    		// 获取之前以当前bean名称注册的beanDefinition
    		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    		// 如果注册过
    		if (existingDefinition != null) {
    			// 如果不允许bean定义覆盖,则抛出异常
    			if (!isAllowBeanDefinitionOverriding()) {
    				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
    			} // 如果角色被内部的beanDefinition覆盖,记录修改到日志
    			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
    				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
    				if (logger.isInfoEnabled()) {
    					logger.info("Overriding user-defined bean definition for bean '" + beanName +
    							"' with a framework-generated bean definition: replacing [" +
    							existingDefinition + "] with [" + beanDefinition + "]");
    				}
    			} // 两个bean不同,记录beanDefinition 被覆盖到日志
    			else if (!beanDefinition.equals(existingDefinition)) {
    				if (logger.isDebugEnabled()) {
    					logger.debug("Overriding bean definition for bean '" + beanName +
    							"' with a different definition: replacing [" + existingDefinition +
    							"] with [" + beanDefinition + "]");
    				}
    			}// 最终只淡出的记录一下beanDefinition 覆盖记录
    			else {
    				if (logger.isTraceEnabled()) {
    					logger.trace("Overriding bean definition for bean '" + beanName +
    							"' with an equivalent definition: replacing [" + existingDefinition +
    							"] with [" + beanDefinition + "]");
    				}
    			}
    
    			// 将新的beanDefinition记录到beanDefinitionMap中
    			this.beanDefinitionMap.put(beanName, beanDefinition);
    		}
    		// 如果之前未注册过beanDefinition
    		else {
    			// 如果已经有bean创建过了(不一定是当前bean)
    			if (hasBeanCreationStarted()) {
    				// Cannot modify startup-time collection elements anymore (for stable iteration)
    				synchronized (this.beanDefinitionMap) {
    					// 将beanDefinition 放入缓存
    					this.beanDefinitionMap.put(beanName, beanDefinition);
    					// 更新beanDefinitionNames,将当前的元素添加进去
    					// 这里没有锁 beanDefinitionNames,是否存在并发问题:
    					// 不会,对beanDefinitionNames的修改,锁的都是beanDefinitionMap,没有问题
    					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
    					updatedDefinitions.addAll(this.beanDefinitionNames);
    					updatedDefinitions.add(beanName);
    					this.beanDefinitionNames = updatedDefinitions;
    					// 移除已经手动注册的单例bean
    					removeManualSingletonName(beanName);
    				}
    			}
    			else {
    				// Still in startup registration phase
    				// 没有bean被初始化过,注册解析的beanDefinition
    				this.beanDefinitionMap.put(beanName, beanDefinition);
    				// 记录已经解析过得beanDefinition,这里没有并发问题,因为在这种case 还在开始的注册阶段,不用加锁
    				this.beanDefinitionNames.add(beanName);
    				// 再移除一遍 已经注册的beanDefinition,不移除,并发会存在问题
    				removeManualSingletonName(beanName);
    			}
    			this.frozenBeanDefinitionNames = null;
    		}
    		// 如果 beanDefinition 已经存在,且单例的bean已创建完成
    		if (existingDefinition != null || containsSingleton(beanName)) {
    			// 重新设置beanDefinition
    			resetBeanDefinition(beanName);
    		}
    		else if (isConfigurationFrozen()) {
    			clearByTypeCache();
    		}
    	}
    

    其中在resetBeanDefinition中,存在函数销毁已创建的bean:destroySingleton,最终调用org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroyBean方法

    	/**
    	 * bean 及其相关信息被销毁后,在getBean时会重新解析beanDefinition 并重新生成
    	 *
    	 * Destroy the given bean. Must destroy beans that depend on the given
    	 * bean before the bean itself. Should not throw any exceptions.
    	 * @param beanName the name of the bean
    	 * @param bean the bean instance to destroy
    	 */
    	protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
    		// Trigger destruction of dependent beans first...
    		Set<String> dependencies;
    		// 删除依赖当前bean的bean
    		synchronized (this.dependentBeanMap) {
    			// Within full synchronization in order to guarantee a disconnected Set
    			dependencies = this.dependentBeanMap.remove(beanName);
    		}
    		if (dependencies != null) {
    			if (logger.isTraceEnabled()) {
    				logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
    			}
    			for (String dependentBeanName : dependencies) {
    				destroySingleton(dependentBeanName);
    			}
    		}
    
    		// Actually destroy the bean now...
    		if (bean != null) {
    			try {
    				bean.destroy();
    			}
    			catch (Throwable ex) {
    				if (logger.isWarnEnabled()) {
    					logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
    				}
    			}
    		}
    
    		// Trigger destruction of contained beans...
    		Set<String> containedBeans;
    		// 移除当前bean中包换的所有bean
    		synchronized (this.containedBeanMap) {
    			// Within full synchronization in order to guarantee a disconnected Set
    			containedBeans = this.containedBeanMap.remove(beanName);
    		}
    		if (containedBeans != null) {
    			for (String containedBeanName : containedBeans) {
    				destroySingleton(containedBeanName);
    			}
    		}
    
    		// Remove destroyed bean from other beans' dependencies.
    		// 移除其他bean依赖当前bean的记录
    		synchronized (this.dependentBeanMap) {
    			for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
    				Map.Entry<String, Set<String>> entry = it.next();
    				Set<String> dependenciesToClean = entry.getValue();
    				dependenciesToClean.remove(beanName);
    				if (dependenciesToClean.isEmpty()) {
    					it.remove();
    				}
    			}
    		}
    
    		// Remove destroyed bean's prepared dependency information.
    		// 移除销毁bean的依赖信息
    		this.dependenciesForBeanMap.remove(beanName);
    	}
    

    在看懂销毁一个bean是删除了哪些信息,其实间接的也就明白了初始化bean时都干了哪些事情

    I am chris, and what about you?
  • 相关阅读:
    sqlalchemy的orm的高级用法,分组,排序,聚合等方法
    flask的SQLAlchemy,连接数据库的增删改查操作
    wtforms的form表单的高级用法
    初始wtforms表单,以及简单使用
    命令启动flask以及自定义命令
    MySQL5.5安装教程
    Java设计模式-策略模式实际应用场景
    Java设计模式-策略模式详解
    Oracle数据库之FORALL与BULK COLLECT语句
    代理模式详解(静态代理和动态代理的区别以及联系)
  • 原文地址:https://www.cnblogs.com/arax/p/14783310.html
Copyright © 2011-2022 走看看