createBeanInstance
:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. Class<?> beanClass = resolveBeanClass(mbd, beanName); // 如果不为null,并且还不是public的访问权限 并且还nonPublicAccessAllowed为false 那就抛异常吧 // 题外话:nonPublicAccessAllowed为true的情况下(默认值),即使你不是public的也ok if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } // 你可以自己通过Supplier来创建Bean,最终交给obtainFromSupplier包装成BeanWrapper Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } //通过工厂方法创建 支持工厂方法方式创建Bean if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... //一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器 //在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析 boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } // 首次进入,resolved为false。 // 说一下:ConstructorResolver,就是找到合适的构造器给你去实例化一个Bean(会结合Spring容器进行一起解析) if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { return instantiateBean(beanName, mbd); } } // Need to determine the constructor... // 执行BeanPostProcesso#determineCandidateConstructors 自己去决定使用哪个构造器,可能会返回一批构造器哟 // 这里我们很熟悉的`AutowiredAnnotationBeanPostProcessor`就实现了这个方法,可以智能去找出一个合适的构造器. // 这里需要注意了,因为我们的Child的属性HelloService里并没有书写@Autowired属性,所以这里最终的返回结果是null================这个需要注意Spring的处理(空构造就不用交给autowireConstructor处理了,自己直接new吧) // 需要注意的是:若我们自己写了一个构造 public Child(HelloService helloService) { this.helloService = helloService; } 那么它就会拿到,然后走下面让Spring执行构造器的注入的 // 旁白:如果你只有空构造,那就直接instantiateBean,否则会自动去走Spring的构造器注入的逻辑 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // No special handling: simply use no-arg constructor. // 所以我们当前的Child,只有空构造器,所以就只能走这里啦 // 这个方法的逻辑比较简单,我就不贴了。主要是用InstantiationStrategy策略器进行实例化,至于它是什么东东?文末的时候我会解释的 return instantiateBean(beanName, mbd); }
该方法执行完成之后,我们对象就被创建了,但仅仅还只是创建好哦。下面继续看:
populateBean
: populate:居住于; 生活于; 大致意思就是给Bean的各个属性赋值
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (bw == null) { if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. boolean continueWithPropertyPopulation = true; // 因为已经实例化了,对象已经创建了,所以这里立马执行了InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation方法 // 单反只有其中一个返回了false,相当于告诉容器我都处理好了,那么后面的赋值操作就Spring容器就不再处理了 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } //以对象的方式存储健值对,比存储在map会更加灵活 //PropertyValues 是用来管理PropertyValue的 一般情况下为null PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); // 那么接下来,就开始干正事了~~~~ // 这里需要注意的是:我们知道上面我们自己传进来的是byType,所以这个的if是能够进来的,最终能够定位autowireByType让它去实现注入功能。 //所以我们的helloService字段要不要@Autowired要不要无所谓(要了也只是重复操作而已,但是我建议显示的指明吧) //但是被Spring扫描Scan管理的Bean们(或者其余Bean),如果你想要给他字段注入属性值,必须必须使用@Autowired注解,从而交给后置处理器AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues这个方法去处理 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. // 按类型自动装配。一般都会走这里,通过类型的匹配,来给属性赋值,实现注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { // 它的步骤相对简单:显示BeanUtils.getWriteMethodParameter(pd)拿到set方法(所以,这里需要注意,若没有set方法,这里是注入不进去的,这个没@Autowired强大) // 然后去解析去容器里面找对应的依赖,也是resolveDependency方法(最终由DefaultListableBeanFactory去实现的) // 这里需要注意:注入的时候isSimpleProperty不会被注入的(包括基本数据类型、Integer、Long。。。 //甚至还包括Enum、CharSequence(显然就包含了Spring)、Number、Date、URI、URL、Locale、Class等等) // 但是,但是,但是标注@Autowired是能够注入的哦,哪怕是String、Integer等等 // 标注了@Autowired,没有找到反倒为报错 No qualifying bean of type 'java.lang.String' 。。。注意这些区别 autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { if (pvs == null) { pvs = mbd.getPropertyValues(); } PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { // 开始执行InstantiationAwareBeanPostProcessor#postProcessPropertyValues // 这里主要施工的又是我们大名鼎鼎的AutowiredAnnotationBeanPostProcessor它了,他会根据所有标注有@Autpwired注解地方,执行注入(非常重要) for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } //applyPropertyValues和PropertyValues密切相关,在后面相关专题在详细讲解 会回到这里的,持续关注~ // 作用:Apply the given property values, resolving any runtime references if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } }
至此,一个Bean的实例化、初始化操作可以完成了一大部分了(各字段、属性的赋值也都已经ok了嘛~),那么还剩下一些收尾工作:比如init方法、post-construct方法之类的,就交给
initializeBean
: 初始化Bean(调用一些初始化方法)