接着 我们正式开始学习获取 bean 实例方法,该方法是Spring 最核心的方法,也是最难的方法,我们首先不能扣太多的细节,先从一个比较简单的实例化的依赖注入入手。

  1. @Override
  2. public Object getBean(String name) throws BeansException {
  3. // 获取name对应的bean实例,如果不存在,则创建一个
  4. return doGetBean(name, null, null, false);
  5. }

doGetBean 方法详解。

  1. protected <T> T doGetBean(
  2. String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
  3. throws BeansException {
  4. // 1.解析beanName,主要是解析别名、去掉FactoryBean的前缀“&”
  5. String beanName = transformedBeanName(name);
  6. Object bean;
  7. // 2.从Spring的三级缓存中获取bean,解决循环依赖的主要的思想
  8. // 当A依赖B,B返回来也依赖A的时候,这个时候获取到的A就是从Spring的第三级缓存中获取到
  9. Object sharedInstance = getSingleton(beanName);
  10. // 6.如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存
  11. if (!typeCheckOnly) {
  12. markBeanAsCreated(beanName);
  13. }
  14. try {
  15. // 7.根据beanName重新获取MergedBeanDefinition(步骤6将MergedBeanDefinition删除了,这边获取一个新的)
  16. RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
  17. checkMergedBeanDefinition(mbd, beanName, args);
  18. // 8.拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean
  19. String[] dependsOn = mbd.getDependsOn();
  20. if (dependsOn != null) {
  21. // 8.1 遍历当前bean依赖的bean名称集合
  22. for (String dep : dependsOn) {
  23. // 8.2 检查dep是否依赖于beanName,即检查是否存在循环依赖
  24. if (isDependent(beanName, dep)) {
  25. // 8.3 如果是循环依赖则抛异常
  26. throw new BeanCreationException("Circular depends-on relationship between '" );}
  27. registerDependentBean(dep, beanName);
  28. try {
  29. getBean(dep);
  30. }
  31. catch (NoSuchBeanDefinitionException ex) {
  32. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  33. "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
  34. }
  35. }
  36. }
  37. // Create bean instance.创建bean实例
  38. // scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
  39. if (mbd.isSingleton()) {
  40. sharedInstance = getSingleton(beanName, () -> {
  41. try {
  42. // ****调用createBean创建Bean实例****
  43. return createBean(beanName, mbd, args);
  44. }
  45. });
  46. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  47. }
  48. }
  49. // 10.检查所需类型是否与实际的bean对象的类型匹配
  50. if (requiredType != null && !requiredType.isInstance(bean)) {
  51. T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
  52. if (convertedBean == null) {
  53. throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
  54. }
  55. return convertedBean;
  56. }
  57. return (T) bean;
  58. }

createBean方法总体流程

  1. @Override
  2. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  3. throws BeanCreationException {
  4. RootBeanDefinition mbdToUse = mbd;
  5. // 1.解析beanName对应的Bean的类型,例如:com.joonwhee.open.demo.service.impl.UserServiceImpl
  6. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  7. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  8. // 如果resolvedClass存在,并且mdb的beanClass类型不是Class,并且mdb的beanClass不为空(则代表beanClass存的是Class的name),
  9. // 则使用mdb深拷贝一个新的RootBeanDefinition副本,并且将解析的Class赋值给拷贝的RootBeanDefinition副本的beanClass属性,
  10. // 该拷贝副本取代mdb用于后续的操作
  11. mbdToUse = new RootBeanDefinition(mbd);
  12. mbdToUse.setBeanClass(resolvedClass);
  13. }
  14. try {
  15. // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  16. // 3.实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例,达到“短路”效果
  17. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  18. // 4.如果bean不为空,则会跳过Spring默认的实例化过程,直接使用返回的bean
  19. if (bean != null) {
  20. return bean;
  21. }
  22. }
  23. // 5.创建Bean实例(真正创建Bean的方法)
  24. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  25. return beanInstance;
  26. }

doCreateBean方法

  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
  2. throws BeanCreationException {
  3. // Instantiate the bean.
  4. // 1.新建Bean包装类
  5. BeanWrapper instanceWrapper = null;
  6. if (mbd.isSingleton()) {
  7. // 2.如果是FactoryBean,则需要先移除未完成的FactoryBean实例的缓存
  8. // *********重点*********
  9. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  10. }
  11. if (instanceWrapper == null) {
  12. // 3.根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrapper
  13. instanceWrapper = createBeanInstance(beanName, mbd, args);
  14. }
  15. // 4.拿到创建好的Bean实例
  16. final Object bean = instanceWrapper.getWrappedInstance();
  17. // 5.拿到Bean实例的类型
  18. Class<?> beanType = instanceWrapper.getWrappedClass();
  19. if (beanType != NullBean.class) {
  20. mbd.resolvedTargetType = beanType;
  21. }
  22. // Allow post-processors to modify the merged bean definition.
  23. // 6.应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition,
  24. // Autowired注解正是通过此方法实现注入类型的预解析
  25. synchronized (mbd.postProcessingLock) {
  26. if (!mbd.postProcessed) {
  27. try {
  28. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  29. }
  30. catch (Throwable ex) {
  31. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  32. "Post-processing of merged bean definition failed", ex);
  33. }
  34. mbd.postProcessed = true;
  35. }
  36. }
  37. // 7.判断是否需要提早曝光实例:单例 && 允许循环依赖 && 当前bean正在创建中
  38. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  39. isSingletonCurrentlyInCreation(beanName));
  40. if (earlySingletonExposure) {
  41. // 8.提前曝光beanName的ObjectFactory,放入到Sprign的三级缓存中
  42. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  43. }
  44. // Initialize the bean instance.初始化bean实例。
  45. Object exposedObject = bean;
  46. try {
  47. // 9.对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例
  48. populateBean(beanName, mbd, instanceWrapper);
  49. exposedObject = initializeBean(beanName, exposedObject, mbd);
  50. }
  51. //......
  52. return exposedObject;
  53. }

createBeanInstance创建Bean实例方法

  1. protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
  2. // Make sure bean class is actually resolved at this point.
  3. // 解析bean的类型信息,
  4. Class<?> beanClass = resolveBeanClass(mbd, beanName);
  5. // beanClass != null && 当前类不是public && 不允许访问非公共构造函数和方法。抛出异常
  6. if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
  7. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  8. "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
  9. }
  10. // 1. 是否有bean的 Supplier 接口,如果有,通过回调来创建bean
  11. Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
  12. if (instanceSupplier != null) {
  13. return obtainFromSupplier(instanceSupplier, beanName);
  14. }
  15. // 2. 如果工厂方法不为空,则使用工厂方法初始化策略
  16. // 通过 @Bean 注解方法注入的bean或者xml 配置factory-method属性注入的
  17. // BeanDefinition 会存在这个值。而注入这个bean的方法就是工厂方法。后面会详细解读
  18. if (mbd.getFactoryMethodName() != null) {
  19. // 执行工厂方法,创建bean
  20. return instantiateUsingFactoryMethod(beanName, mbd, args);
  21. }
  22. /* 3. 尝试使用构造函数构建bean,后面详解
  23. * 经过上面两步,Spring确定没有其他方式来创建bean,所以打算使用构造函数来进行创建bean。
  24. * 但是 bean 的构造函数可能有多个,需要确定使用哪一个。
  25. */
  26. // resolved 表示构造函数是否已经解析完成
  27. boolean resolved = false;
  28. // autowireNecessary: 是否需要自动注入(即是否需要解析构造函数参数)
  29. boolean autowireNecessary = false;
  30. if (args == null) {
  31. // 2.加锁
  32. synchronized (mbd.constructorArgumentLock) {
  33. // 一个类可能有多个不同的构造函数,每个构造函数参数列表不同,所以调用前需要根据参数锁定对应的构造函数或工程方法
  34. // 如果这个bean的构造函数或者工厂方法已经解析过了,会保存到 mbd.resolvedConstructorOrFactoryMethod 中。这里来判断是否已经解析过了。
  35. if (mbd.resolvedConstructorOrFactoryMethod != null) {
  36. // 2.1 则将resolved标记为已解析
  37. resolved = true;
  38. // 2.2 根据constructorArgumentsResolved判断是否需要自动注入
  39. autowireNecessary = mbd.constructorArgumentsResolved;
  40. }
  41. }
  42. }
  43. // 如果已经解析过则使用功能解析好的构造函数方法,不需要再次解析。
  44. // 这里的是通过 mbd.resolvedConstructorOrFactoryMethod 属性来缓存解析过的构造函数。
  45. if (resolved) {
  46. if (autowireNecessary) {
  47. // 3.1 需要自动注入,则执行构造函数自动注入
  48. return autowireConstructor(beanName, mbd, null, null);
  49. } else {
  50. // 3.2 否则使用默认的构造函数进行bean的实例化
  51. return instantiateBean(beanName, mbd);
  52. }
  53. }
  54. // Spring通过调用后置处理器的determineCandidateConstructors方法将所有被@Autowired标注的构造方法给查找了出来,
  55. // 如果不存在缓存则需要进行解析,这里通过 determineConstructorsFromBeanPostProcessors 方法调用了
  56. // SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors 的后处理器方法来进行解析,
  57. // Spring 默认的实现在AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors 方法中。
  58. // 通过determineCandidateConstructors 方法获取到了候选的构造函数(因为满足条件的构造函数可能不止一个,需要进行进一步的选择)。
  59. Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  60. if (ctors != null ||
  61. mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
  62. mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
  63. // 5.如果ctors不为空 || mbd的注入方式为AUTOWIRE_CONSTRUCTOR || mdb定义了构造函数的参数值 || args不为空,则执行构造函数自动注入
  64. return autowireConstructor(beanName, mbd, ctors, args);
  65. }
  66. // No special handling: simply use no-arg constructor.
  67. // 6.没有特殊处理,则使用默认的构造函数进行bean的实例化
  68. return instantiateBean(beanName, mbd);
  69. }

创建实例的方法通常有以下几种:
Supplier方法 : 留给用户可以进行扩展的方法

  1. public class CustomSupplierBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
  2. //自己定义了 supplier
  3. @Override
  4. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
  5. AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("student");
  6. beanDefinition.setInstanceSupplier(SupplierObject::create);
  7. System.out.println("do Custom Supplier BeanFactoryPostProcessor");
  8. }
  9. // 没有定义 supplier,这样也可以。
  10. @Override
  11. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
  12. AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("student");
  13. beanDefinition.setInstanceSupplier(()->{
  14. Student custom = new Student();
  15. custom.setStudentName("zhao");
  16. return custom;
  17. });
  18. System.out.println("do Custom Supplier BeanFactoryPostProcessor");
  19. }
  20. }

工厂方法:https://www.cnblogs.com/javastack/p/13431216.html
构造函数自动装配(通常指带有参数的构造函数)

简单实例化
1、通过BeanUtils,它使用了JVM的反射功能来生成Java对象实例
2、用CGLIB来生成,CGLIB是一种常用的字节码生成器的类库

  1. @Override
  2. public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
  3. // Don't override the class with CGLIB if no overrides.
  4. // 如果MethOverrides为空.
  5. // spring有两个标签参数会产生MethodOverrides ,分别是 lookup-method,replaced-method
  6. // 其中replaced-method使用方法 https://blog.csdn.net/wang0907/article/details/114325252
  7. if (bd.getMethodOverrides().isEmpty()) {
  8. Constructor<?> constructorToUse;
  9. synchronized (bd.constructorArgumentLock) {
  10. // 获取bd.resolvedConstructorOrFactoryMethod已解析的构造器或工厂方法
  11. constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
  12. // 如果为空
  13. if (constructorToUse == null) {
  14. final Class<?> clazz = bd.getBeanClass();
  15. // 如果是接口,抛出异常
  16. if (clazz.isInterface()) {
  17. throw new BeanInstantiationException(clazz, "Specified class is an interface");
  18. }
  19. try {
  20. else {
  21. //通过bean的类clazz来得到声明的构造函数
  22. constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
  23. }
  24. // 并赋值回给bd.resolvedConstructorOrFactoryMethod
  25. bd.resolvedConstructorOrFactoryMethod = constructorToUse;
  26. }
  27. catch (Throwable ex) {
  28. throw new BeanInstantiationException(clazz, "No default constructor found", ex);
  29. }
  30. }
  31. }
  32. // 通过BeanUtils方法实例化bean
  33. return BeanUtils.instantiateClass(constructorToUse);
  34. }
  35. else {
  36. // Must generate CGLIB subclass.
  37. // 如果MethodOverrides不为空,生成cglib的子类
  38. return instantiateWithMethodInjection(bd, beanName, owner);
  39. }
  40. }