主干流程

beanFactory.preInstantiateSingletons();

  1. @Override
  2. public void preInstantiateSingletons() throws BeansException {
  3. if (logger.isTraceEnabled()) {
  4. logger.trace("Pre-instantiating singletons in " + this);
  5. }
  6. // Iterate over a copy to allow for init methods which in turn register new bean definitions.
  7. // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
  8. // 拷贝一份bean
  9. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
  10. // Trigger initialization of all non-lazy singleton beans...
  11. for (String beanName : beanNames) {
  12. // 取bean的元数据,这里有个合并的动作
  13. RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
  14. // 处理非抽象,并且是单例,非懒加载的bean
  15. if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
  16. if (isFactoryBean(beanName)) {
  17. // 工厂bean
  18. Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
  19. if (bean instanceof FactoryBean) {
  20. FactoryBean<?> factory = (FactoryBean<?>) bean;
  21. boolean isEagerInit;
  22. // 如果是SmartFactoryBean的实例
  23. if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
  24. // 安全检查
  25. isEagerInit = AccessController.doPrivileged(
  26. (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
  27. getAccessControlContext());
  28. }
  29. else {
  30. isEagerInit = (factory instanceof SmartFactoryBean &&
  31. ((SmartFactoryBean<?>) factory).isEagerInit());
  32. }
  33. if (isEagerInit) {
  34. getBean(beanName);
  35. }
  36. }
  37. }
  38. else {
  39. // 其他的bean
  40. getBean(beanName);
  41. }
  42. }
  43. }
  44. // bean 创建后的回调
  45. // Trigger post-initialization callback for all applicable beans...
  46. for (String beanName : beanNames) {
  47. Object singletonInstance = getSingleton(beanName);
  48. if (singletonInstance instanceof SmartInitializingSingleton) {
  49. SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
  50. if (System.getSecurityManager() != null) {
  51. AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
  52. smartSingleton.afterSingletonsInstantiated();
  53. return null;
  54. }, getAccessControlContext());
  55. }
  56. else {
  57. smartSingleton.afterSingletonsInstantiated();
  58. }
  59. }
  60. }
  61. }

片段:合并 bean 定义

getMergedLocalBeanDefinition 合并操作。将 BeanDefinition转换成 RootBeanDefinition。

  • 如果 Abean extends Object ,那么 RootBeanDefinition 就是 Abean 本身的 BeanDefinition;
  • 如果 Abean extends Bbean,那么就需要合并 Abean 和 Bean 的BeanDefinition。

spring-context | org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition

  1. protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
  2. // Quick check on the concurrent map first, with minimal locking.
  3. // 检查下缓存,有的话,并且不需要合并的直接返回
  4. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
  5. if (mbd != null && !mbd.stale) {
  6. return mbd;
  7. }
  8. return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
  9. }

调用 getMergedBeanDefinition

  1. protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
  2. throws BeanDefinitionStoreException {
  3. return getMergedBeanDefinition(beanName, bd, null);
  4. }

重载的方法

  1. protected RootBeanDefinition getMergedBeanDefinition(
  2. String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
  3. throws BeanDefinitionStoreException {
  4. // ConcurrentHashMap 内部是线程安全的,但是把单个操作组合起来不一定是安全的。比如 map.put(key,value++)。
  5. synchronized (this.mergedBeanDefinitions) {
  6. RootBeanDefinition mbd = null;
  7. RootBeanDefinition previous = null;
  8. // Check with full lock now in order to enforce the same merged instance.
  9. if (containingBd == null) {
  10. mbd = this.mergedBeanDefinitions.get(beanName);
  11. }
  12. if (mbd == null || mbd.stale) {
  13. previous = mbd;
  14. if (bd.getParentName() == null) {
  15. // Use copy of given root bean definition.
  16. if (bd instanceof RootBeanDefinition) {
  17. mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
  18. }
  19. else {
  20. mbd = new RootBeanDefinition(bd);
  21. }
  22. }
  23. else {
  24. // Child bean definition: needs to be merged with parent.
  25. BeanDefinition pbd;
  26. try {
  27. String parentBeanName = transformedBeanName(bd.getParentName());
  28. if (!beanName.equals(parentBeanName)) {
  29. pbd = getMergedBeanDefinition(parentBeanName);
  30. }
  31. else {
  32. BeanFactory parent = getParentBeanFactory();
  33. if (parent instanceof ConfigurableBeanFactory) {
  34. pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
  35. }
  36. else {
  37. throw new NoSuchBeanDefinitionException(parentBeanName,
  38. "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
  39. "': cannot be resolved without a ConfigurableBeanFactory parent");
  40. }
  41. }
  42. }
  43. catch (NoSuchBeanDefinitionException ex) {
  44. throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
  45. "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
  46. }
  47. // Deep copy with overridden values.
  48. mbd = new RootBeanDefinition(pbd);
  49. mbd.overrideFrom(bd);
  50. }
  51. // Set default singleton scope, if not configured before.
  52. if (!StringUtils.hasLength(mbd.getScope())) {
  53. mbd.setScope(SCOPE_SINGLETON);
  54. }
  55. // A bean contained in a non-singleton bean cannot be a singleton itself.
  56. // Let's correct this on the fly here, since this might be the result of
  57. // parent-child merging for the outer bean, in which case the original inner bean
  58. // definition will not have inherited the merged outer bean's singleton status.
  59. if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
  60. mbd.setScope(containingBd.getScope());
  61. }
  62. // Cache the merged bean definition for the time being
  63. // (it might still get re-merged later on in order to pick up metadata changes)
  64. if (containingBd == null && isCacheBeanMetadata()) {
  65. this.mergedBeanDefinitions.put(beanName, mbd);
  66. }
  67. }
  68. if (previous != null) {
  69. copyRelevantMergedBeanDefinitionCaches(previous, mbd);
  70. }
  71. return mbd;
  72. }
  73. }

合并操作有不同的情况

这里分两种情况去看代码:

  1. 实例化普通的 bean ,比如 Sbean
  2. 实例化有很多父类的 bean,比如 Abean extends Bbean,Bbean extends Cbean …

    情况1:单个bean

    首先进入方法:getMergedLocalBeanDefinition(String beanName)
    1. protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
    2. // Quick check on the concurrent map first, with minimal locking.
    3. // 检查下缓存,有的话,并且不需要合并的直接返回
    4. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
    5. if (mbd != null && !mbd.stale) {
    6. return mbd;
    7. }
    8. return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
    9. }

这里肯定没有缓存,所以进入下一个方法:
getMergedBeanDefinition(String beanName, BeanDefinition bd)

  1. protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
  2. throws BeanDefinitionStoreException {
  3. return getMergedBeanDefinition(beanName, bd, null);
  4. }

直接进入重载方法:getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) 。如下代码,删除了不会走的分支。

  1. protected RootBeanDefinition getMergedBeanDefinition(
  2. String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
  3. throws BeanDefinitionStoreException {
  4. // ConcurrentHashMap 内部是线程安全的,但是把单个操作组合起来不一定是安全的。比如 map.put(key,value++)。
  5. synchronized (this.mergedBeanDefinitions) {
  6. RootBeanDefinition mbd = null;
  7. RootBeanDefinition previous = null;
  8. // 这个操作后,mbd==null
  9. if (containingBd == null) {
  10. mbd = this.mergedBeanDefinitions.get(beanName);
  11. }
  12. if (mbd == null || mbd.stale) {
  13. previous = mbd; // null
  14. if (bd.getParentName() == null) {
  15. // Use copy of given root bean definition.
  16. // 不是
  17. if (bd instanceof RootBeanDefinition) {
  18. mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
  19. }
  20. else {
  21. // 直接返回这个
  22. mbd = new RootBeanDefinition(bd);
  23. }
  24. }
  25. else {
  26. ......
  27. }
  28. // Set default singleton scope, if not configured before.
  29. if (!StringUtils.hasLength(mbd.getScope())) {
  30. mbd.setScope(SCOPE_SINGLETON);
  31. }
  32. // 加入缓存
  33. if (containingBd == null && isCacheBeanMetadata()) {
  34. this.mergedBeanDefinitions.put(beanName, mbd);
  35. }
  36. }
  37. return mbd;
  38. }
  39. }

情况2:有继承关系的bean

比如 Abean extends Bbean,Bextends Object 。前几步骤都一样,直接进入重载方法:getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
因为 Abean 的 parent 不为空,所以进入分支:

  1. BeanDefinition pbd;
  2. try {
  3. // 得到父bean的名称
  4. String parentBeanName = transformedBeanName(bd.getParentName());
  5. if (!beanName.equals(parentBeanName)) {
  6. // 如果不是当前bean,取父bean的BeanDefinition,递归
  7. pbd = getMergedBeanDefinition(parentBeanName);
  8. }
  9. else {
  10. BeanFactory parent = getParentBeanFactory();
  11. if (parent instanceof ConfigurableBeanFactory) {
  12. pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
  13. }
  14. else {
  15. throw new NoSuchBeanDefinitionException(parentBeanName,
  16. "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
  17. "': cannot be resolved without a ConfigurableBeanFactory parent");
  18. }
  19. }
  20. }
  21. catch (NoSuchBeanDefinitionException ex) {
  22. throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
  23. "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
  24. }
  25. // Deep copy with overridden values.
  26. mbd = new RootBeanDefinition(pbd);
  27. mbd.overrideFrom(bd);

在 pbd = getMergedBeanDefinition(parentBeanName);
方法上会不断查找父bean定义。然后利用方法进行合并。

  1. mbd = new RootBeanDefinition(pbd);
  2. mbd.overrideFrom(bd);

测试代码

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd">
  3. <beans>
  4. <bean id="dog" class="cn.lichenghao.entity.Dog" lazy-init="false">
  5. <property name="name">
  6. <value>Dog11</value>
  7. </property>
  8. <property name="age">
  9. <value>31</value>
  10. </property>
  11. </bean>
  12. <bean id="cat" class="cn.lichenghao.entity.Cat" parent="animal">
  13. <property name="name">
  14. <value>Cat123</value>
  15. </property>
  16. <property name="age">
  17. <value>3</value>
  18. </property>
  19. </bean>
  20. <bean id="animal" class="cn.lichenghao.entity.Animal">
  21. <property name="canRun">
  22. <value>true</value>
  23. </property>
  24. </bean>
  25. </beans>

3个 bean ```java package cn.lichenghao.entity;

public class Animal {

  1. private boolean canRun;
  2. public Animal() {
  3. }
  4. public boolean isCanRun() {
  5. return canRun;
  6. }
  7. public void setCanRun(boolean canRun) {
  8. this.canRun = canRun;
  9. }

}

  1. ```java
  2. package cn.lichenghao.entity;
  3. public class Dog {
  4. private String name;
  5. private Integer age;
  6. public Dog() {
  7. System.out.println("Dog init!!");
  8. }
  9. public Dog(String name, Integer age) {
  10. System.out.println("Dog init!!");
  11. this.name = name;
  12. this.age = age;
  13. }
  14. public void say(){
  15. System.out.println("wwwwwwwww");
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23. public Integer getAge() {
  24. return age;
  25. }
  26. public void setAge(Integer age) {
  27. this.age = age;
  28. }
  29. }
  1. package cn.lichenghao.entity;
  2. public class Cat extends Animal {
  3. private String name;
  4. private Integer age;
  5. public Cat() {
  6. }
  7. public Cat(String name, Integer age) {
  8. super();
  9. this.name = name;
  10. this.age = age;
  11. }
  12. public String getName() {
  13. return name;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public Integer getAge() {
  19. return age;
  20. }
  21. public void setAge(Integer age) {
  22. this.age = age;
  23. }
  24. }

启动 IOC 测试

  1. public class AppDog {
  2. public static void main(String[] args) {
  3. // 根据配置文件加载bean
  4. ClassPathXmlApplicationContext classPathXmlApplicationContext
  5. = new ClassPathXmlApplicationContext("dog.xml");
  6. }
  7. }

片段:判断 Bean 是否为 FactoryBean

通过代码可以看出,分为两种情况的 Bean ,一种是 FactoryBean,一种是其他的 Bean。

  1. public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
  2. String beanName = transformedBeanName(name);
  3. Object beanInstance = getSingleton(beanName, false);
  4. if (beanInstance != null) {
  5. return (beanInstance instanceof FactoryBean);
  6. }
  7. // No singleton instance found -> check bean definition.
  8. if (!containsBeanDefinition(beanName)
  9. && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
  10. // No bean definition found in this factory -> delegate to parent.
  11. return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
  12. }
  13. return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
  14. }

然后再过安全检查,特权处理。

  1. if (isFactoryBean(beanName)) {
  2. // 工厂bean
  3. Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
  4. if (bean instanceof FactoryBean) {
  5. FactoryBean<?> factory = (FactoryBean<?>) bean;
  6. boolean isEagerInit;
  7. // 如果是SmartFactoryBean的实例
  8. if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
  9. // 安全检查
  10. isEagerInit = AccessController.doPrivileged(
  11. (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
  12. getAccessControlContext());
  13. }
  14. else {
  15. isEagerInit = (factory instanceof SmartFactoryBean &&
  16. ((SmartFactoryBean<?>) factory).isEagerInit());
  17. }
  18. if (isEagerInit) {
  19. getBean(beanName);
  20. }
  21. }
  22. }

准备完毕

所有的准备工作已经完毕,接下来就是实例化 bean 的大流程。
Z10NEXG95H7gOsjY6jKOd.png