registerBeanDefinition

84 阅读15分钟

registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;

该方法和上面的描述密不可分咱就直接上代码和代码注释了:

@Override
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 {
            ((AbstractBeanDefinition) beanDefinition).validate();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                    "Validation of bean definition failed", ex);
        }
    }
    //在注册beanDefinition的时候判断该名字有没有被注册
    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    if (existingDefinition != null) {//代表没有被注入到beanDefinitionMap中
        if (!isAllowBeanDefinitionOverriding()) {
            throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
        }
        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 + "]");
            }
        }
        else if (!beanDefinition.equals(existingDefinition)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Overriding bean definition for bean '" + beanName +
                        "' with a different definition: replacing [" + existingDefinition +
                        "] with [" + beanDefinition + "]");
            }
        }
        else {
            if (logger.isTraceEnabled()) {
                logger.trace("Overriding bean definition for bean '" + beanName +
                        "' with an equivalent definition: replacing [" + existingDefinition +
                        "] with [" + beanDefinition + "]");
            }
        }
        this.beanDefinitionMap.put(beanName, beanDefinition);
    //如果没有就会进入到else中
    } else {
        //这个时候又要判断,当前spring容器是否开始实例化bean了?
        //判断的依据是hasBeanCreationStarted()方法是否有值?
        /*
         *protected boolean hasBeanCreationStarted() {
         * 	return !this.alreadyCreated.isEmpty();
         *}
         */
        //其实就是判断这个alreadyCreated set集合是否有值?
        if (hasBeanCreationStarted()) {
            // Cannot modify startup-time collection elements anymore (for stable iteration)
            // 这句的意思:当我们开始实例某个bean的时候,一定要确保当前被实例化的bean的beanDefinition信息是固定的,是不可修改的。
            // 这就是beanFactory.freezeConfiguration();方法主要做的一件事情,其实讲白了就是防止出现线程安全的问题,你想想一个线程在修改BeanDefinition一个线程在读取当前Bean的BeanDefinition是不是就很有问题?
            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;
                //如果你注册了beanDefinition的名称和手动注册的BeanDefinitionMap中某个相同则删除手工注册的
                removeManualSingletonName(beanName);
            }
        }
        //如果进入到这个else中表示Bean已经开始实例化了
        else {
            // Still in startup registration phase
            // 这里的注释为什么说,当前的容器仍处于启动注册阶段就可以不像上面的if块中加synchronized来防止并发问题,就是因为他都还没有开始实例化呢,
            // 所以你在这个时候进行修改啥的都没有问题,当前的Bean的BeanDefinition本身就是不确定的,你修改了也只是修改了我BeanDefinitionMap中的beanDefinition而已,
            // 这个时候spring并没有通过beanDefinition将当前的Bean进行实例化,所以这里不加synchronized是没有问题的。
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            //如果你注册了beanDefinition的名称和手动注册的BeanDefinitionMap中某个相同则删除手工注册的
            removeManualSingletonName(beanName);
        }
        this.frozenBeanDefinitionNames = null;
    }

    if (existingDefinition != null || containsSingleton(beanName)) {
        resetBeanDefinition(beanName);
    }
    else if (isConfigurationFrozen()) {
        clearByTypeCache();
    }
}

注意看,在上述代码的第64和75行的方法removeManualSingletonName(beanName);对于他的解释是:如果你注册了beanDefinition的名称和手动注册的BeanDefinitionMap中某个相同则删除手工注册的。什么意思呢?

  1. 在spring中我们绝大部分的bean是通过beanDefiniton进行实例化的,但是spring同时也允许你跳过这一步,直接将一个Bean丢到单例池中,但是这里的单例池并不是singletionObjects,是manualSingletonNames,有点区别:手动注册的单例的名称列表,按注册顺序。
/** List of names of manually registered singletons, in registration order. */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
  1. 其实他的作用很简单就是在spring容器中一个bean只能对应的是一个beanName,k-v结构嘛,不然spring咋知道你到底找的是谁?
  2. 过程就是,他先去manualSingletonNames集合中判断如果有重复的beanName的话就直接删除嘛,由于最后这里的beanName还是对应着singletionObjects中Bean实例的,这样就保证了就算是你自己直接注入的一个bean在我的spring的容器中也不会重复嘛。
  3. 为了验证这个想法,咱们可以做个测试。
@Component("name1")
public class TestBean {
}
@Component("name2")
public class TestBean02 {
}
@Configuration
@ComponentScan("com.lukp.beanFactoryPostProcessor.test")
public class TestBeanFactoryPostProcessor {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(TestBeanFactoryPostProcessor.class);
		ioc.getBean(TestBean.class);
		System.out.println("");
	}
}
  1. 我们走debug,查看mergedBeanDefinitions。

  1. 说一下在singletonObject中存在着两种来源的Bean,一种是spring自己提供的bean,一种是程序员提供的bean。
  2. 同时也有两种提供的方式:
  • 一种是spring在实例化bean的时候,从beanDefintionMap中遍历一个一个的去实例化。
  • 另一种是通过registerBeanDefinition()的方式,你提供一个BeanName和Bean的类型。
  1. 有个问题:

  1. 看上面的两张图片,其实都是spring注入bean实例的方式,但是你会发现到其实大部分的都是spring内置的bean,意思就是创建spring容器时,spring自己就会创建的bean。那么为什么不直接通过上述的其中完成bean的实例化呢?
  2. 我们看register()方法:
ioc.register(TestBean.class);
public void register(Class<?>... componentClasses) {
    Assert.notEmpty(componentClasses, "At least one component class must be specified");
    this.reader.register(componentClasses);
}
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) {
    	//这里就直接将传进来,想要注册的Bean的进行BeanDefinition构建了
		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());
		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.setLazyIn t(true);
				}
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		if (customizers != null) {
			for (BeanDefinitionCustomizer customizer : customizers) {
				customizer.customize(abd);
			}
		}

		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
    // Register bean definition under primary name.
    String beanName = definitionHolder.getBeanName();
    //直接将beanName和BeanDefinition放入到bean的注册表中
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    // Register aliases for bean name, if any.
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}
  1. 这是我们的直接通过BeanDefinition的方法来完成Bean实例化,后面的流程也就是spring从BeanDefinitionMap中遍历一个一个的实例化,不用多讲。
  2. 其实也有另一个方法ioc.registerBeanDefinition("xx", new RootBeanDefinition(TestBean.class));
  3. 下面来看一下,另一种方式,直接将Bean注册到Spring-context中。
ioc.getBeanFactory().registerSingleton("beanName",new Bean对象);
  1. 并且两种的注入的方式其实,你可以看到在beanDefinitionMap中和manualSingletonNames中存在的结果是不一样的,你按照第一种是在beanDefinitionMap里,第二种是在manualSingletonNames中。
  2. 并且我们可以证明上面我们说的理论是正确的:
AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext();
ioc.register(TestBean.class);
//manualSingletonNames
ioc.getBeanFactory().registerSingleton("xxx",new TestBean());
//beanDefinitionMap
ioc.registerBeanDefinition("xxx", new RootBeanDefinition(TestBean.class));
//实例化
ioc.refresh();
  1. 当代码是这个样子的时候,你会发现spring会将manualSingletonNames中的xxx去掉,而是要beanDefinitionMap的xxx。

表面的现象看完了,我们要较为深入的去了解springRegisterBeanDefinition方法到底是怎样运作的:

  1. 假设现在我在spring完成了初始化,这个时候不会进入到if (hasBeanCreationStarted())块中,
@Override
	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 {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
		//在注册beanDefinition的时候判断该名字有没有被注册
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			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 + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		//如果没有就会进入到else中
		} else {
			//这个时候又要判断,当前spring容器是否开始实例化bean了?
			//判断的依据是hasBeanCreationStarted()方法是否有值?
			/*
			 *protected boolean hasBeanCreationStarted() {
			 * 	return !this.alreadyCreated.isEmpty();
			 *}
			 */
			//其实就是判断这个alreadyCreated set集合是否有值?
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				// 这句的意思:当我们开始实例某个bean的时候,一定要确保当前被实例化的bean的beanDefinition信息是固定的,是不可修改的。
				// 这就是beanFactory.freezeConfiguration();方法主要做的一件事情,其实讲白了就是防止出现线程安全的问题,你想想一个线程在修改BeanDefinition一个线程在读取当前Bean的BeanDefinition是不是就很有问题?
				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;
					//如果你注册了beanDefinition的名称和手动注册的BeanDefinitionMap中某个相同则删除手工注册的
					removeManualSingletonName(beanName);
				}
			}
			//如果进入到这个else中表示Bean已经开始实例化了
			else {
				// Still in startup registration phase
				// 这里的注释为什么说,当前的容器仍处于启动注册阶段就可以不像上面的if块中加synchronized来防止并发问题,就是因为他都还没有开始实例化呢,
				// 所以你在这个时候进行修改啥的都没有问题,当前的Bean的BeanDefinition本身就是不确定的,你修改了也只是修改了我BeanDefinitionMap中的beanDefinition而已,
				// 这个时候spring并没有通过beanDefinition将当前的Bean进行实例化,所以这里不加synchronized是没有问题的。
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				//如果你注册了beanDefinition的名称和手动注册的BeanDefinitionMap中某个相同则删除手工注册的
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}
		//判断register的beanDefinition已经存在(根据名字判断)
		if (existingDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
		//如果被冻结了,则表示可能是有缓存
		else if (isConfigurationFrozen()) {
			clearByTypeCache();
		}
	}
  1. 这个时候在你自己写的register()方法中注入的对象,会生效:
public void destroySingleton(String beanName) {
		//存储到单例池中
		super.destroySingleton(beanName);
		//如果是程序员手动添加Beand,则添加到ManualSingletonName中
		removeManualSingletonName(beanName);
		//清除缓存,原始因为有新的bean要注入,在这里添加完毕要清除缓存,防止并发问题
		clearByTypeCache();
	}
  1. 被添加到Singletons或者是ManualSingletonName中(看你添加的方式不同罢了)。
  2. 最后添加完成后都会清除缓存,防止产生并发问题。
  3. 上述讲的是当前在spring实例化完成后,去hasBeanCreationStarted()方法的返回值,如果是为true说明还有没被初始化的Bean,当然我们上述讲的是hasBeanCreationStarted()为false的时候,也就是所有的bean被初始化完了。
  4. 那么如果bean没有被初始化完成就会进入到if (hasBeanCreationStarted())语句块中。
// Cannot modify startup-time collection elements anymore (for stable iteration)
// 这句的意思:当我们开始实例某个bean的时候,一定要确保当前被实例化的bean的beanDefinition信息是固定的,是不可修改的。
// 这就是beanFactory.freezeConfiguration();方法主要做的一件事情,其实讲白了就是防止出现线程安全的问题,你想想一个线程在修改BeanDefinition一个线程在读取当前Bean的BeanDefinition是不是就很有问题?
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;
    //如果你注册了beanDefinition的名称和手动注册的BeanDefinitionMap中某个相同则删除手工注册的
    removeManualSingletonName(beanName);
}
  1. 在这里说一点要进入到这个代码中是有些条件的,在这里我先说一下spring提供的前提:
  • spring允许你对生成好的beanDefinition进行覆盖:
    • 在两个bd相同的情况下。
    • 在两个bd不相同的情况:role不同。
    • 在两个bd不相同的情况:role相同。
    • role其实是一个优先级。
//在注册beanDefinition的时候判断该名字有没有被注册
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
    if (!isAllowBeanDefinitionOverriding()) {
        throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
    }
    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 + "]");
        }
    }
    else if (!beanDefinition.equals(existingDefinition)) {
        if (logger.isDebugEnabled()) {
            logger.debug("Overriding bean definition for bean '" + beanName +
                    "' with a different definition: replacing [" + existingDefinition +
                    "] with [" + beanDefinition + "]");
        }
    }
    else {
        if (logger.isTraceEnabled()) {
            logger.trace("Overriding bean definition for bean '" + beanName +
                    "' with an equivalent definition: replacing [" + existingDefinition +
                    "] with [" + beanDefinition + "]");
        }
    }
    //判断优先级完成后,也还是会put到beanDefinitionMap
    this.beanDefinitionMap.put(beanName, beanDefinition);
}
  1. 最后如果说beanDefinition注册完成(上述的两种大情况),就会走到下面的这个代码中:其实也是清除缓存了和已经被初始化完成的bean。
//判断register的beanDefinition已经存在(根据名字判断)
if (existingDefinition != null || containsSingleton(beanName)) {
    //清除allBeanNamesByType
    //把单例池中的bean也remove
    resetBeanDefinition(beanName);
}
//如果被冻结了,则表示可能是有缓存
else if (isConfigurationFrozen()) {
    //所以还是要清除一下缓存
    clearByTypeCache();
}
  1. ok,其实对registerBeanDefinition()这个方法讲这么多,就是为了使得我们明白这个冻结的方法到底是干啥的。

上面做了这么多的铺垫,下面我们要扯一下void freezeConfiguration();方法的作用了:

  1. 在上文我们说了注册bean的相关方法和冻结bean的相关方法,我现在来看一段代码:
@Component
public class FreezeConfiguration implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		AbstractBeanDefinition e = (AbstractBeanDefinition) beanFactory.getBeanDefinition("e");
		//调用冻结方法
		beanFactory.freezeConfiguration();
		//虽然上述调用冻结方法,但是下面设置当前Bean为SINGLETON也还是会起作用
		e.setScope(BeanDefinition.SCOPE_SINGLETON);
	}
}
  1. 上述的代码使用了freezeConfiguration();方法和设置e这个bean的scope是单例的。
  2. 但是我们想一下在设置e这个bean的为单例bean之前我们其实已经把beanFactory冻结了,那么对于下面的设置是不会生效的,但是你最终你debug还是会发现你设置的单例生效了。这是为什么呢?
  3. 好了话不都说咱们开始画图:

  1. 为什么会有上面这张图的关系?为什么spring在实例化BeanDefintion的时候还有merg这个动作呢?
  2. 我现在来看下面这段代码,spring中的beanDefinition是有继承关系的:
public class P {
	public P() throws UnsupportedEncodingException {
		System.setOut(new PrintStream(System.out, true, "UTF-8"));
		System.out.println("你好我是P的构造器,我被调用了...");
	}
}
public class C {
	public C() throws UnsupportedEncodingException {
		System.setOut(new PrintStream(System.out, true, "UTF-8"));
		System.out.println("我是c的构造器,我被调用了...");
	}
}
public class TestSpring {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		//1.创建一个P类的rootBeanDefinition
		RootBeanDefinition pbd = new RootBeanDefinition(P.class);
		//2.设置p这个BeanDefinition的scope属性为单例的
		pbd.setScope(AbstractBeanDefinition.SCOPE_SINGLETON);
		//3.创建一个子类的BeanDefinition,他父类为p这个BeanDefinition
		ChildBeanDefinition cbd = new ChildBeanDefinition("p");
		//4.将C类设置到cbd这个BeanDefinition实例中
		cbd.setBeanClass(C.class);
		//5.注入两个BeanDefinition实例到context中
		context.registerBeanDefinition("p", pbd);
		context.registerBeanDefinition("c", cbd);
		//6.实例化context
		context.refresh();
	}
}
  1. 我可以看到上面有两个类P和C,在启动类中我们创建了一个RootBeanDefinition的对象并将P类放了进去,代表的是创建了一个Root级别的BeanDefintion(同时这个RootBeanDefinition也可以为普通的BeanDefinition),这时我们设置了P的BeanDefiniton的属性为Singleton,接下来就可以体现出何为继承。
  2. 看到在第8行代码创建了ChildBeanDefinition这个类,并且放入到p类到构造参数中,代表的是我创建了一个子类beanDefiniton,他的父类是p,然后指定这个孩子类的BeanClass为C。
  3. 我们验证一下他们的父子关系是否成立,当我现在点击启动后,在我两个类中我都写了一个无参构造器并且都有一段话会输出,并且我设置了singleton属性,也就是说当我的程序启动,spring会将这个两个bean注入到spring容器中,也就意味着两个构造器中的话会输出。
  4. 结果也是和我们想象的是一样的两个类的构造器果然输出了!
  5. 我们通过上面的例子说明了BeanDefintion之间是有继承关系的,但是!现在spring弃用这种方式来做了BeanDefiniton的父子关系了,而是改用一个叫GenericBeanDefinition的类来做beanDefintion的父子关系。
  6. 我们现在改用GenericBeanDefinition来替换上面使用RootBeanDefinition和ChildBeanDefinition。
public class TestSpring {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		//父类bean p
		GenericBeanDefinition p = new GenericBeanDefinition();
		p.setScope(AbstractBeanDefinition.SCOPE_SINGLETON);
		p.setBeanClass(P.class);
		//子类bean c
		GenericBeanDefinition c = new GenericBeanDefinition();
		c.setParentName("p");
		c.setBeanClass(C.class);
		//注入两个Bean到context中
		context.registerBeanDefinition("p", p);
		context.registerBeanDefinition("c", c);
		context.refresh();
	}
}
  1. 输出的结果也是和我们预期的一样的。
  2. 我现在深入原理去看一下,打个断点在15行,你会发现在beanFactory中的beanDefinitonMap中的c这个key的value中的scope属性并没有变化还是null。
  3. 那是因为你现在只是把两个bean注入到了springContext中并没有开始实例化bean的动作。
  4. 那这个时候我们等待context refresh()完成再看,c的scope属性是否是继承了父Bean的scope呢?
  5. ok,我现在再回头来想,前面是不是说过其实spring在实例化BeanDefintion的时候并不是从BeanDefinitonMap中取的,其实是从mergedBeanDefinitions这个集合中获取的,这个才是经过一系列的beanDefiniton的合并之后完整的beanDefiniton,通过获取到这里面的BeanDefintion来完成Bean的实例化操作。
  6. 并且通过Debug我们也可以看到真相了,确实在mergedBeanDefinitions中的c类的beanDefintion信息中scope为singloten。

  1. 所以在这里我们可以下一个结论就是说,spring在初始化的时候其实并不是从BeanDefinitionMap中获取相关的BeanDefintion来进行bean的实例化的。
  2. 至于为什么spring在实例化bean的之前还要去mergBean的操作,原因是:加入我实例化当前的bean他还有父类呢?咋办?我要先把他的beanDefinition定于清晰再说。

  1. 我们在执行bean的实例化前要检查当前的beanDefinition是否是RootBeanDefinition,如果是直接过和beanDefintionMap中对应的bd进行merg,最后完成实例化,如果不是rootBeanDefinition,那么就会new一个RootBD,并且去寻找到bd的父类,进行属性的填充,完成后之后进行merg动作,最后讲merg完成BD进行实例化。
  2. 看到上图,在进入到MergeBeanDefinition之前会执行spring内置的beanFacotryPostProcessor,并且是通过getBean()方法来获取,拿到之后就执行BeanFactoryPostProcessor方法,进行bean的实例化。如果没有getBean()方法第一次的去寻找的时候没有找到,就会去BDMap中寻找。
  3. 下面的内容太多了,我们现在只需要精简的讲一下,spring内置的bean为什么需要这两种方式存在在单例池中?
  • 直接注册一个对象,他不具备完整性。
  • bd去实例化一个对象,他要做一些事情。