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中某个相同则删除手工注册的。什么意思呢?
- 在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);
- 其实他的作用很简单就是在spring容器中一个bean只能对应的是一个beanName,k-v结构嘛,不然spring咋知道你到底找的是谁?
- 过程就是,他先去manualSingletonNames集合中判断如果有重复的beanName的话就直接删除嘛,由于最后这里的beanName还是对应着singletionObjects中Bean实例的,这样就保证了就算是你自己直接注入的一个bean在我的spring的容器中也不会重复嘛。
- 为了验证这个想法,咱们可以做个测试。
@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("");
}
}
- 我们走debug,查看mergedBeanDefinitions。
- 说一下在singletonObject中存在着两种来源的Bean,一种是spring自己提供的bean,一种是程序员提供的bean。
- 同时也有两种提供的方式:
- 一种是spring在实例化bean的时候,从beanDefintionMap中遍历一个一个的去实例化。
- 另一种是通过registerBeanDefinition()的方式,你提供一个BeanName和Bean的类型。
- 有个问题:
- 看上面的两张图片,其实都是spring注入bean实例的方式,但是你会发现到其实大部分的都是spring内置的bean,意思就是创建spring容器时,spring自己就会创建的bean。那么为什么不直接通过上述的其中完成bean的实例化呢?
- 我们看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);
}
}
}
- 这是我们的直接通过BeanDefinition的方法来完成Bean实例化,后面的流程也就是spring从BeanDefinitionMap中遍历一个一个的实例化,不用多讲。
- 其实也有另一个方法ioc.registerBeanDefinition("xx", new RootBeanDefinition(TestBean.class));
- 下面来看一下,另一种方式,直接将Bean注册到Spring-context中。
ioc.getBeanFactory().registerSingleton("beanName",new Bean对象);
- 并且两种的注入的方式其实,你可以看到在beanDefinitionMap中和manualSingletonNames中存在的结果是不一样的,你按照第一种是在beanDefinitionMap里,第二种是在manualSingletonNames中。
- 并且我们可以证明上面我们说的理论是正确的:
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();
- 当代码是这个样子的时候,你会发现spring会将manualSingletonNames中的xxx去掉,而是要beanDefinitionMap的xxx。
表面的现象看完了,我们要较为深入的去了解springRegisterBeanDefinition方法到底是怎样运作的:
- 假设现在我在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();
}
}
- 这个时候在你自己写的register()方法中注入的对象,会生效:
public void destroySingleton(String beanName) {
//存储到单例池中
super.destroySingleton(beanName);
//如果是程序员手动添加Beand,则添加到ManualSingletonName中
removeManualSingletonName(beanName);
//清除缓存,原始因为有新的bean要注入,在这里添加完毕要清除缓存,防止并发问题
clearByTypeCache();
}
- 被添加到Singletons或者是ManualSingletonName中(看你添加的方式不同罢了)。
- 最后添加完成后都会清除缓存,防止产生并发问题。
- 上述讲的是当前在spring实例化完成后,去hasBeanCreationStarted()方法的返回值,如果是为true说明还有没被初始化的Bean,当然我们上述讲的是hasBeanCreationStarted()为false的时候,也就是所有的bean被初始化完了。
- 那么如果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);
}
- 在这里说一点要进入到这个代码中是有些条件的,在这里我先说一下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);
}
- 最后如果说beanDefinition注册完成(上述的两种大情况),就会走到下面的这个代码中:其实也是清除缓存了和已经被初始化完成的bean。
//判断register的beanDefinition已经存在(根据名字判断)
if (existingDefinition != null || containsSingleton(beanName)) {
//清除allBeanNamesByType
//把单例池中的bean也remove
resetBeanDefinition(beanName);
}
//如果被冻结了,则表示可能是有缓存
else if (isConfigurationFrozen()) {
//所以还是要清除一下缓存
clearByTypeCache();
}
- ok,其实对registerBeanDefinition()这个方法讲这么多,就是为了使得我们明白这个冻结的方法到底是干啥的。
上面做了这么多的铺垫,下面我们要扯一下void freezeConfiguration();方法的作用了:
- 在上文我们说了注册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);
}
}
- 上述的代码使用了freezeConfiguration();方法和设置e这个bean的scope是单例的。
- 但是我们想一下在设置e这个bean的为单例bean之前我们其实已经把beanFactory冻结了,那么对于下面的设置是不会生效的,但是你最终你debug还是会发现你设置的单例生效了。这是为什么呢?
- 好了话不都说咱们开始画图:
- 为什么会有上面这张图的关系?为什么spring在实例化BeanDefintion的时候还有merg这个动作呢?
- 我现在来看下面这段代码,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();
}
}
- 我可以看到上面有两个类P和C,在启动类中我们创建了一个RootBeanDefinition的对象并将P类放了进去,代表的是创建了一个Root级别的BeanDefintion(同时这个RootBeanDefinition也可以为普通的BeanDefinition),这时我们设置了P的BeanDefiniton的属性为Singleton,接下来就可以体现出何为继承。
- 看到在第8行代码创建了ChildBeanDefinition这个类,并且放入到p类到构造参数中,代表的是我创建了一个子类beanDefiniton,他的父类是p,然后指定这个孩子类的BeanClass为C。
- 我们验证一下他们的父子关系是否成立,当我现在点击启动后,在我两个类中我都写了一个无参构造器并且都有一段话会输出,并且我设置了singleton属性,也就是说当我的程序启动,spring会将这个两个bean注入到spring容器中,也就意味着两个构造器中的话会输出。
- 结果也是和我们想象的是一样的两个类的构造器果然输出了!
- 我们通过上面的例子说明了BeanDefintion之间是有继承关系的,但是!现在spring弃用这种方式来做了BeanDefiniton的父子关系了,而是改用一个叫GenericBeanDefinition的类来做beanDefintion的父子关系。
- 我们现在改用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();
}
}
- 输出的结果也是和我们预期的一样的。
- 我现在深入原理去看一下,打个断点在15行,你会发现在beanFactory中的beanDefinitonMap中的c这个key的value中的scope属性并没有变化还是null。
- 那是因为你现在只是把两个bean注入到了springContext中并没有开始实例化bean的动作。
- 那这个时候我们等待context refresh()完成再看,c的scope属性是否是继承了父Bean的scope呢?
- ok,我现在再回头来想,前面是不是说过其实spring在实例化BeanDefintion的时候并不是从BeanDefinitonMap中取的,其实是从mergedBeanDefinitions这个集合中获取的,这个才是经过一系列的beanDefiniton的合并之后完整的beanDefiniton,通过获取到这里面的BeanDefintion来完成Bean的实例化操作。
- 并且通过Debug我们也可以看到真相了,确实在mergedBeanDefinitions中的c类的beanDefintion信息中scope为singloten。
- 所以在这里我们可以下一个结论就是说,spring在初始化的时候其实并不是从BeanDefinitionMap中获取相关的BeanDefintion来进行bean的实例化的。
- 至于为什么spring在实例化bean的之前还要去mergBean的操作,原因是:加入我实例化当前的bean他还有父类呢?咋办?我要先把他的beanDefinition定于清晰再说。
- 我们在执行bean的实例化前要检查当前的beanDefinition是否是RootBeanDefinition,如果是直接过和beanDefintionMap中对应的bd进行merg,最后完成实例化,如果不是rootBeanDefinition,那么就会new一个RootBD,并且去寻找到bd的父类,进行属性的填充,完成后之后进行merg动作,最后讲merg完成BD进行实例化。
- 看到上图,在进入到MergeBeanDefinition之前会执行spring内置的beanFacotryPostProcessor,并且是通过getBean()方法来获取,拿到之后就执行BeanFactoryPostProcessor方法,进行bean的实例化。如果没有getBean()方法第一次的去寻找的时候没有找到,就会去BDMap中寻找。
- 下面的内容太多了,我们现在只需要精简的讲一下,spring内置的bean为什么需要这两种方式存在在单例池中?
- 直接注册一个对象,他不具备完整性。
- bd去实例化一个对象,他要做一些事情。