目录

一、概要

二、createBean():创建bean实例

三、resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)

四、doCreateBean():真正创建bean实例的方法

五、createBeanInstance():实例化bean对象

六、applyMergedBeanDefinitionPostProcessors():应用后置处理器 MergedBeanDefinitionPostProcessor,允许修改 MergedBeanDefinition

七、addSingletonFactory():添加给定的单例工厂以构建指定的单例

八、populateBean():属性填充

九、initializeBean():初始化bean

十、registerDisposableBeanIfNecessary():注册DisposableBean

十一、总结


一、概要

通过前面一篇文章对getBean流程的分析,我们大致了解了从容器获取一个bean的主要步骤,但是我们暂且忽略了Spring具体创建bean实例的过程,所以本篇文章我们需要继续深入分析createBean()流程。

二、createBean():创建bean实例

前面介绍到,如果是单例bean,会先调用getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法,尝试从缓存中获取对应的bean实例,如果获取不到的话,才会执行singletonFactory.getObject()回调方法 ==> 实际上是执行createBean()方法创建bean实例

// 创建单例 bean 实例
if (mbd.isSingleton()) {  //单例作用域// 第二个参数是一个ObjectFactory,是一个函数式接口,当调用ObjectFactory的getObject()方法的时候,实际上调用的是createBean(beanName, mbd, args)// 也就是说在getSingleton()方法内部调用ObjectFactory的getObject()方法的时候,会回调到这里的createBean(beanName, mbd, args)创建bean,接着才会调用下面的getObjectForBeanInstance()方法// 8、第八步:尝试从缓存中获取对应的bean实例,获取不到的话,则执行singletonFactory的回调 -> createBean()创建beansharedInstance = getSingleton(beanName, () -> {try {// 创建bean对象return createBean(beanName, mbd, args);} catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.// 创建失败则销毁destroySingleton(beanName);throw ex;}});// 返回beanName对应的实例对象bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法简述如下:

  1. 尝试从一级缓存(singletonObjects)中获取对应的bean;
  2. 创建单例前的操作,设置bean处于正在创建中状态;
  3. 调用singletonFactory.getObject()执行singletonFactory的回调,实际上是调用createBean()创建bean;
  4. 移除bean处于正在创建中状态;
  5. 如果是新的bean对象,则将bean保存到一级缓存(singletonObjects)、已注册bean缓存(registeredSingletons)中,同时删除二级缓存(earlySingletonObjects)、三级缓存(singletonFactories)中对应的bean信息;

本篇文章分析的重点就是上述标红的部分,即AbstractBeanFactory#createBean()方法。

createBean()方法的处理流程简述如下:

  • 1、第一步:根据bean定义信息和bean名称解析得到bean的Class类型;
  • 2、第二步:验证并准备为此 bean 定义的方法覆盖;
  • 3、第三步:给InstantiationAwareBeanPostProcessor后置处理器一个机会,返回代理对象用来替换目标bean实例;
  • 4、第四步:执行真正创建bean的方法 ==> doCreateBean();
  • 5、第五步:返回创建好的bean实例;
// org.springframework.beans.factory.support.AbstractBeanFactory.createBean
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException;protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.// 1、第一步:根据bean定义信息和bean名称解析得到bean的Class类型Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.try {// 2、第二步:验证并准备为此 bean 定义的方法覆盖// 对overrides属性进行标记和验证,在xml解析阶段,将lookup-method和replace-method两个标签属性,保存在MethodOverrides中mbdToUse.prepareMethodOverrides();} catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.// 3、第三步:给InstantiationAwareBeanPostProcessor后置处理器一个机会,返回代理对象用来替换目标bean实例// 如果返回不为空就直接返回代理bean(AOP功能就是基于这里判断的)// InstantiationAwareBeanPostProcessor: 前置增强方法:postProcessBeforeInstantiation  后置增强方法:postProcessAfterInitializationObject bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {// 如果bean不为空的话,则直接返回,不执行下面的doCreateBean创建bean实例操作return bean;}} catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}try {// 4、第四步:真正创建bean的方法Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}// 5、第五步:返回创建好的bean实例return beanInstance;} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {// A previously detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.throw ex;} catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}
}

三、resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)

给InstantiationAwareBeanPostProcessor后置处理器一个机会,返回代理对象用来替换目标bean实例。如果返回不为空就直接返回代理bean(AOP功能就是基于这里判断的)。

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;// beforeInstantiationResolved: bean是否已解析的状态标识if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.// 1、如果bean不是合成的,并且工厂拥有将在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置增强器// mbd.isSynthetic()方法的作用:返回这个 bean 定义是否是“合成的”,即不是由应用程序本身定义的// hasInstantiationAwareBeanPostProcessors()方法的作用:返回此工厂是否拥有将在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessorif (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {// 2、确定给定 bean 定义的目标类型,主要是针对含有FactoryMethod的Bean进行特殊处理Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {// 3、执行InstantiationAwareBeanPostProcessor的前置增强方法:postProcessBeforeInstantiation()bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {// 4、执行InstantiationAwareBeanPostProcessor的后置增强方法:postProcessAfterInitialization()// 这里需要注意的是:在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])方法// 中,在执行doCreateBean()方法前有个判断,如果bean不为空,则会直接返回,所以需要在这里执行bean的后置增强。// 普通创建bean的后置增强方法:其实是在doCreateBean()方法里面执行的bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}// 5、如果bean不为空,beforeInstantiationResolved标志位设置为true,表示当前bean在实例化前已经解析过mbd.beforeInstantiationResolved = (bean != null);}return bean;
}
  • applyBeanPostProcessorsBeforeInstantiation():在实例化之前执行 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation()方法,该方法可以返回 bean 实例的代理,从而跳过 Spring 默认的实例化过程。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {// 1、获取到工厂中注册的所有BeanPostProcessor后置增强器for (BeanPostProcessor bp : getBeanPostProcessors()) {// 2、判断是否是InstantiationAwareBeanPostProcessor类型if (bp instanceof InstantiationAwareBeanPostProcessor) {// 3、如果类型匹配的话,就直接强转了InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;// 4、执行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);// 5、如果result不为空,说明存在后置处理器返回了bean实例对象,则会跳过doCreateBean()的实例化过程if (result != null) {return result;}}}return null;
}
  • applyBeanPostProcessorsAfterInitialization():如果经过postProcessBeforeInstantiation()方法返回的bean不为空,还需要在这里执行applyBeanPostProcessorsAfterInitialization()后置增强。
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;// 1、获取到工厂中注册的所有BeanPostProcessor后置增强器for (BeanPostProcessor processor : getBeanPostProcessors()) {// 2、执行BeanPostProcessor的后置增强方法postProcessAfterInitialization()Object current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {// 3、如果postProcessAfterInitialization()返回为空,则直接返回,将不会执行后续的BeanPostProcessor后置处理器的增强return result;}// 4、使用增强后的bean current,赋值给result,然后返回result = current;}return result;
}

四、doCreateBean():真正创建bean实例的方法

前面的一些方法都是创建bean实例前的准备工作,到了doCreateBean()才是真正开始创建bean。

doCreateBean()方法的处理流程稍微复杂点,简述一下:

  • 1、如果是单例bean,尝试从未完成创建的包装Bean缓存(factoryBeanInstanceCache)中获取BeanWrapper(bean的包装类), 如果获取成功,还将会清除对应的缓存;
  • 2、完成bean的实例化的方法,根据指定bean使用的策略创建bean的实例,如工厂方法、构造方法自动注入、简单初始化;
  • 3、获取包装器里面刚创建好的bean实例;
  • 4、应用合并后的BeanDefinition后置处理器:执行MergedBeanDefinitionPostProcessor后置处理器增强方法postProcessMergedBeanDefinition();
  • 5、是否允许提前暴露bean对象(即半成品对象);
  • 6、如果允许提前暴露,将会调用addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)方法,将生成bean的工厂ObjectFactory添加到三级缓存(singletonFactories)中;
  • 7、属性填充,对bean各个属性值进行注入,可能存在依赖于其它bean的属性,则会递归初始依赖的bean;
  • 8、初始化Bean,如执行aware接口、执行init-method方法、BeanPostProcessor后置增强等等;
  • 9、如果允许早期暴露,需要进行循环依赖检查;
  • 10、注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理;
  • 11、完成bean的创建并返回;
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// 实例化beanBeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {// 1、如果是单例bean,尝试从未完成创建的包装Bean缓存(factoryBeanInstanceCache)中获取BeanWrapper(bean的包装类), 如果获取成功,还将清除这个缓存//     private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>():FactoryBean名称 ==> BeanWrapperinstanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}// 如果缓存中不存在的话,则调用createBeanInstance创建一个BeanWrapper(bean的包装类)if (instanceWrapper == null) {// 2、完成bean的实例化的方法,根据指定bean使用的策略创建bean的实例,如工厂方法、构造方法自动注入、简单初始化instanceWrapper = createBeanInstance(beanName, mbd, args);}// 3、获取包装器里面刚创建好的bean实例Object bean = instanceWrapper.getWrappedInstance();// 获取实例化对象的类型Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// 允许后处理器修改合并的 bean 定义synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {// 4、应用合并后的BeanDefinition后置处理器:执行MergedBeanDefinitionPostProcessor后置处理器增强方法postProcessMergedBeanDefinition()applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);} catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.// 5、是否允许提前暴露bean对象(即半成品对象)// earlySingletonExposure的值由三部分确定:单例bean && 允许循环依赖 && 当前bean正在创建中// isSingletonCurrentlyInCreation(beanName)的作用:返回指定的单例 bean 当前是否正在创建中// allowCircularReferences:是否允许循环依赖,默认为trueboolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));// 6、如果允许提前暴露,将会调用addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)方法,将生成bean的工厂ObjectFactory添加到三级缓存(singletonFactories)中// addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)是Spring解决循环依赖非常关键的代码if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}// 为避免循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂,将生成bean的工厂添加到三级缓存(singletonFactories)中// 第二个参数同样是一个ObjectFactory,是一个函数式接口,当执行ObjectFactory的getObject()方法的时候,实际上执行的是getEarlyBeanReference(beanName, mbd, bean)// getEarlyBeanReference(beanName, mbd, bean)的作用: 获取早期访问指定 bean 的引用addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// 初始化bean实例Object exposedObject = bean;try {// 7、属性填充,对bean各个属性值进行注入,可能存在依赖于其它bean的属性,则会递归初始依赖的beanpopulateBean(beanName, mbd, instanceWrapper);// 8、初始化Bean,如执行aware接口、执行init-method方法、BeanPostProcessor后置增强等等exposedObject = initializeBean(beanName, exposedObject, mbd);} catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;} else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}}// 9、如果允许早期暴露,需要进行循环依赖检查if (earlySingletonExposure) {// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {// 能进入这里,说明Spring检测到发生了循环依赖// exposedObject == bean:两者相等,说明bean在执行initializeBean()初始化的时候,没有被后置处理器增强,还是原来那个对象if (exposedObject == bean) {exposedObject = earlySingletonReference;} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {// allowRawInjectionDespiteWrapping: 表示是否允许在循环引用的情况下注入原始 bean 实例,即使注入的 bean 最终被增强器增强包装过,默认是false// hasDependentBean(beanName):是否存在其他bean依赖了当前bean// 获取到依赖当前bean的所有bean的beanNameString[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {// 尝试移除bean实例,因为执行到这里,说明exposedObject != bean,也就是bean已经被后置处理器增强,不是原来的对象了,// 他们依赖的是原来的对象,属于脏数据,所以需要移除掉if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {// 使用actualDependentBeans记录那些移除失败的dependentBeanactualDependentBeans.add(dependentBean);}}// 如果存在移除失败的,则需要抛出异常,Spring不允许脏依赖的存在(通过allowRawInjectionDespiteWrapping设置)if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.try {// 10、注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理registerDisposableBeanIfNecessary(beanName, bean, mbd);} catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}// 11、完成bean的创建并返回return exposedObject;
}

下面重点分析doCreateBean()方法中几个关键步骤的实现。

五、createBeanInstance():实例化bean对象

首先尝试从未完成创建的包装Bean缓存(factoryBeanInstanceCache)中获取BeanWrapper(bean的包装类),如果缓存中不存在的话,则会调用createBeanInstance创建一个BeanWrapper(bean的包装类)。

简述createBeanInstance()方法的处理过程:

  • 1、解析bean的Class类型;
  • 2、如果存在用于创建 bean 实例的回调,则从给定的Supplier接口获取一个bean实例;
  • 3、如果存在工厂方法的话,即设置了factory-method,则使用工厂方法进行实例化;
  • 4、如果构造函数和工厂方法已经被解析过,直接使用前面介绍的缓存resolvedConstructorOrFactoryMethod里面解析好的,如果需要自动注入,则执行构造函数自动注入,否则使用默认构造函数进行实例化;
  • 5、传入beanClass和beanName,通过SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors()方法,确定用于给定 bean 的候选构造函数;
  • 6、如果存在用于默认构造的首选构造函数,则执行构造函数的自动注入;
  • 7、如果既不存在工厂方法,也不存在带有参数的构造方法,则使用默认的构造方法进行bean的实例化;

代码如下:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// Make sure bean class is actually resolved at this point.// 1、解析bean的Class类型Class<?> beanClass = resolveBeanClass(mbd, beanName);// 如果bean的Class类型不为空、bean不是public修饰的、且bean不允许访问非公共构造函数和方法,那么Spring会抛异常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());}// 2、如果存在用于创建 bean 实例的回调,则从给定的Supplier接口获取一个bean实例Supplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}// 3、如果存在工厂方法的话,即设置了factory-method,则使用工厂方法进行实例化if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}// Shortcut when re-creating the same bean...// 标识构造函数和工厂方法是否已经被解析过boolean resolved = false;// 是否需要自动注入boolean autowireNecessary = false;// 实例化bean的参数为空if (args == null) {synchronized (mbd.constructorArgumentLock) {// resolvedConstructorOrFactoryMethod其实是一个缓存,存放已经解析过的构造函数和工厂方法,防止重复解析if (mbd.resolvedConstructorOrFactoryMethod != null) {// 如果缓存不为空,则修改resolved为true,标记为已解析resolved = true;// 是否需要自动注入的值取决于mbd的constructorArgumentsResolved属性(将构造函数参数标记为已解析的包可见字段)autowireNecessary = mbd.constructorArgumentsResolved;}}}// 4、如果构造函数和工厂方法已经被解析过,直接使用前面介绍的缓存resolvedConstructorOrFactoryMethod里面解析好的,如果需要自动注入,// 则执行构造函数自动注入,否则使用默认构造函数进行实例化if (resolved) {if (autowireNecessary) {// 如果需要自动注入,则执行构造函数自动注入return autowireConstructor(beanName, mbd, null, null);} else {// 如果不需要自动注入,则使用默认构造函数进行实例化return instantiateBean(beanName, mbd);}}// Candidate constructors for autowiring?// 5、传入beanClass和beanName,通过SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors()方法,确定用于给定 bean 的候选构造函数// 因为一个类可以有多个构造方法,每个构造方法都有不同的参数,所以需要根据参数以及类型去判断最终调用哪一个构造方法并进行实例化Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);// 满足下面四个条件的其中一个,都会执行构造函数的自动注入://     a.determineConstructorsFromBeanPostProcessors()方法返回的构造方法不为空;//   b.bean的注入类型为AUTOWIRE_CONSTRUCTOR;//  c.存在bean定义的构造函数参数值;//    d.用于构造函数或工厂方法调用的显式参数不为空;if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {// 执行构造函数的自动注入return autowireConstructor(beanName, mbd, ctors, args);}// Preferred constructors for default construction?// 6、如果存在用于默认构造的首选构造函数,则执行构造函数的自动注入ctors = mbd.getPreferredConstructors();if (ctors != null) {// 构造函数自动注入return autowireConstructor(beanName, mbd, ctors, null);}// 7、如果既不存在工厂方法,也不存在带有参数的构造方法,则使用默认的构造方法进行bean的实例化return instantiateBean(beanName, mbd);
}

在本例中,因为都没有指定其他创建bean的回调、SmartInstantiationAwareBeanPostProcessor等,所以是通过默认的构造方法来实例化bean,如下图就是通过反射获取默认构造方法创建对象的过程:

六、applyMergedBeanDefinitionPostProcessors():应用后置处理器 MergedBeanDefinitionPostProcessor,允许修改 MergedBeanDefinition

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {// 1、获取到bean工厂所有已经注册的BeanPostProcessor后置处理器for (BeanPostProcessor bp : getBeanPostProcessors()) {// 2、判断是否属于MergedBeanDefinitionPostProcessor类型if (bp instanceof MergedBeanDefinitionPostProcessor) {MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;// 3、类型匹配的话,执行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition()方法// postProcessMergedBeanDefinition()方法的作用:对指定 bean 的给定MergedBeanDefinition进行后处理bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);}}
}

调用 MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition()增强方法,对指定 bean 的给定MergedBeanDefinition进行后置处理,例如@Autowired注解就是在这个方法对元数据进行预解析,读者可通过AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition查看。

七、addSingletonFactory():添加给定的单例工厂以构建指定的单例

如果允许提前暴露,通过addSingletonFactory()方法将生成bean的工厂ObjectFactory添加到三级缓存(singletonFactories)中,这是Spring解决循环依赖非常关键的代码。

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");// 加锁synchronized (this.singletonObjects) {// 1、如果一级缓存中不存在当前beanName的时候,才能进if判断if (!this.singletonObjects.containsKey(beanName)) {// 2、将beanName => ObjectFactory的映射关系添加到三级缓存中,注意添加的是创建bean的对象工厂singletonFactorythis.singletonFactories.put(beanName, singletonFactory);// 3、从二级缓存中移除当前beanNamethis.earlySingletonObjects.remove(beanName);// 4、将beanName添加到已注册单例集合中this.registeredSingletons.add(beanName);}}
}

通过addSingletonFactory()提前暴露的对象工厂到底是在哪里使用了呢?

其实是在DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)方法中使用到,singletonObject = singletonFactory.getObject(); 执行singletonFactory.getObject()的时候,实际上就是执行getEarlyBeanReference()方法获取早期bean的对象引用。

下面对Spring中涉及的三级缓存做一个简单的介绍:

//  一级缓存:用于保存beanName和创建bean实例之间的关系,beanName -> bean instance
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);// 三级缓存:用于保存beanName和创建bean的工厂之间的关系,beanName -> ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);// 二级缓存:用于保存beanName和创建bean实例之间的关系,beanName -> bean instance
// 与一级缓存的区别:当一个单例bean被放在二级缓存中后,当bean还在创建过程中,就可以通过getBean方法获取到了,目的是用来检测循环引用
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
  • getEarlyBeanReference():获取早期访问指定 bean的引用
// 获取早期访问指定 bean 的引用,通常用于解析循环引用
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {Object exposedObject = bean;// 1、如果bean 定义不是“合成的”,并且工厂中存在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置处理器,才会进入下面的逻辑if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {// 2、获取工厂中所有已注册的BeanPostProcessor后置增强器for (BeanPostProcessor bp : getBeanPostProcessors()) {// 3、判断是否属于SmartInstantiationAwareBeanPostProcessor类型if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;// 4、类型匹配的话,则执行SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference()方法获取bean的早期引用// getEarlyBeanReference()方法: 此回调使后处理器有机会尽早暴露包装器 - 即在目标 bean 实例完全初始化之前, 默认实现是返回原始的bean对象exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);}}}// 5、如果不存在SmartInstantiationAwareBeanPostProcessor,则直接返回原始的bean对象return exposedObject;
}
  • addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

注意,上述代码中getEarlyBeanReference()方法并不是在这里就执行,这里只是将【() -> getEarlyBeanReference(beanName, mbd, bean)】这个函数式接口作为创建bean的对象工厂,添加到三级缓存中而已,后续解决循环依赖的时候,就会从三级缓存中拿出这个对象工厂,即执行ObjectFactory.getObject()方法的时候,就会回调getEarlyBeanReference(beanName, mbd, bean)方法,获取到提前暴露的bean的早期引用,从而解决循环依赖。

八、populateBean():属性填充

属性填充,对bean各个属性值进行注入,可能存在依赖于其它bean的属性,则会递归初始化依赖的bean。

简述一下populateBean()的处理过程:

  • 1、针对bean的包装器是否为空、是否存在为此 bean 定义的属性值,做不同的处理。如果bean的包装器为空,但是又存在为此 bean 定义的属性值,Spring则会抛出BeanCreationException异常;如果没有为此 bean 定义的属性值,即没有可填充的属性,则直接返回;
  • 2、如果bean定义不是合成的,并且工厂中存在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置处理器,则需要处理执行它的postProcessAfterInstantiation()方法;
  • 3、获取到bean定义中封装好的属性值;
  • 4、根据设置的自动注入方式(名称或者类型)获取属性bean(递归getBean)存入PropertyValues中;
  • 5、如果存在InstantiationAwareBeanPostProcessor后置处理器,需要执行InstantiationAwareBeanPostProcessor的postProcessProperties()以及postProcessPropertyValues()方法回调;
  • 6、执行依赖检查,对应depend-on属性;
  • 7、属性填充的具体过程,即将属性值赋值到beanWrapper中bean实例的具体属性中;
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {// 1、针对bean的包装器是否为空、是否存在为此 bean 定义的属性值,做不同的处理if (bw == null) {// 如果bean的包装器为空,但是又存在为此 bean 定义的属性值,Spring则会抛出BeanCreationException异常// 因为属性填充就是要给BeanWrapper 中的 bean 实例中的属性进行赋值的过程,存在属性,但是BeanWrapper为空,也就是BeanWrapper 中的 bean 实例为空,那么显然不行if (mbd.hasPropertyValues()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");} else {// 如果没有为此 bean 定义的属性值,即没有可填充的属性,则直接返回// 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.// InstantiationAwareBeanPostProcessor后置处理器:可以在属性设置前修改bean// 2、如果bean定义不是合成的,并且工厂中存在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置处理器,则需要处理执行它的postProcessAfterInstantiation()方法if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {// 获取到bean工厂所有已经注册的BeanPostProcessorfor (BeanPostProcessor bp : getBeanPostProcessors()) {// 判断是否属于InstantiationAwareBeanPostProcessor类型if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;// 如果类型匹配的话,将会执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法// postProcessAfterInstantiation()方法:在bean实例化后,属性填充之前被调用,允许修改bean的属性,默认实现是返回trueif (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {// 如果postProcessAfterInstantiation()方法返回false,则跳过后面的属性填充过程return;}}}}// 3、获取到bean定义中封装好的属性值PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);// 4、根据设置的自动注入方式(名称或者类型)获取属性bean(递归getBean)存入PropertyValues中int resolvedAutowireMode = mbd.getResolvedAutowireMode();if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// 根据名称自动注入// Add property values based on autowire by name if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}//根据类型自动注入// Add property values based on autowire by type if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}// hasInstAwareBpps:工厂是否存在将在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置处理器boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();// needsDepCheck:是否需要进行依赖检查boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds = null;// 5、如果存在InstantiationAwareBeanPostProcessor后置处理器,需要执行InstantiationAwareBeanPostProcessor的postProcessProperties()以及postProcessPropertyValues()方法回调if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}// 执行InstantiationAwareBeanPostProcessor的postProcessProperties()以及postProcessPropertyValues()方法回调// postProcessProperties(): 允许对填充前的属性进行处理(如对属性的验证)// postProcessPropertyValues(): 对属性值进行修改,通过基于原始的PropertyValues创建一个新的MutablePropertyValues实例,添加或删除特定的值。// 不过目前方法已经被标记为过期,在后续Spring版本中可能会被删除for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}}// 6、执行依赖检查,对应depend-on属性if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}// 依赖检查,对应depend-on属性checkDependencies(beanName, mbd, filteredPds, pvs);}// 7、属性填充的具体过程,即将属性值赋值到beanWrapper中bean实例的具体属性中if (pvs != null) {// 开始填充属性值applyPropertyValues(beanName, mbd, bw, pvs);}
}
  • postProcessAfterInstantiation():可以控制是否继续后面的属性填充过程,如果返回false,则跳过后面的属性填充过程,默认返回true。
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;
}
  • autowireByName():根据名称自动注入
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {// 1、获取需要注入的属性名称数组,注意只获取不是“简单”属性类型(基础类型、枚举、Number等)的那些属性String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);// 2、循环需要注入的属性,根据名称自动注入for (String propertyName : propertyNames) {// 3、判断是否存在名称为propertyName的bean或者bean定义,如果当前工厂中没找到,还会递归所有的父工厂去查找if (containsBean(propertyName)) {// 4、通过getBean从工厂中获取到名称为propertyName的bean实例Object bean = getBean(propertyName);// 5、将propertyName以及对应的属性值bean添加到MutablePropertyValues中pvs.add(propertyName, bean);// 6、注册依赖关系到两个缓存中:dependentBeanMap、dependenciesForBeanMapregisterDependentBean(propertyName, beanName);if (logger.isTraceEnabled()) {logger.trace("Added autowiring by name from bean name '" + beanName +"' via property '" + propertyName + "' to bean named '" + propertyName + "'");}} else {// 7、如果工厂以及父工厂都没有找到名称为propertyName的bean或者bean定义,则不处理这个属性if (logger.isTraceEnabled()) {logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +"' by name: no matching bean found");}}}
}
  • autowireByType():根据类型自动注入
protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {// 1、判断是否存在自定义的TypeConverter,存在则使用自定义的,否则还是使用入参指定的bwTypeConverter converter = getCustomTypeConverter();if (converter == null) {converter = bw;}Set<String> autowiredBeanNames = new LinkedHashSet<>(4);// 2、获取需要注入的属性名称数组,注意只获取不是“简单”属性类型(基础类型、枚举、Number等)的那些属性String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {try {// 3、获取包装对象的特定属性的属性描述符PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);// Don't try autowiring by type for type Object: never makes sense,// even if it technically is a unsatisfied, non-simple property.if (Object.class != pd.getPropertyType()) {// 4、为指定属性的写入方法获取一个新的 MethodParameter 对象,通常指的是获取setter方法MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);// Do not allow eager init for type matching in case of a prioritized post-processor.boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);// 5、解析当前属性所匹配的bean实例,并把解析到的bean实例的beanName存入autowiredBeanNamesObject autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);if (autowiredArgument != null) {// 6、如果解析到的bean实例不为空的话,将propertyName以及对应的属性值autowiredArgument添加到MutablePropertyValues中pvs.add(propertyName, autowiredArgument);}for (String autowiredBeanName : autowiredBeanNames) {// 7、注册依赖关系到两个缓存中:dependentBeanMap、dependenciesForBeanMap,这里是beanName依赖了autowiredBeanNameregisterDependentBean(autowiredBeanName, beanName);if (logger.isTraceEnabled()) {logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +propertyName + "' to bean named '" + autowiredBeanName + "'");}}autowiredBeanNames.clear();}} catch (BeansException ex) {throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);}}
}

九、initializeBean():初始化bean

initializeBean()主要完成如执行aware接口、执行init-method方法、BeanPostProcessor后置增强等工作。

简述initializeBean()方法处理过程:

  • 1、执行Aware方法,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware;
  • 2、执行BeanPostProcessor后置处理器的前置处理方法:postProcessBeforeInitialization(),允许对bean实例进行包装;
  • 3、执行初始化方法,包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-method;
  • 4、执行BeanPostProcessor后置处理器的后置处理方法:postProcessAfterInitialization(),允许对bean实例进行包装;
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {// 1、执行Aware方法,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAwareif (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());} else {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {// 2、执行BeanPostProcessor后置处理器的前置处理方法:postProcessBeforeInitialization(),允许对bean实例进行包装wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 3、执行初始化方法,包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-methodinvokeInitMethods(beanName, wrappedBean, mbd);} catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {// 4、执行BeanPostProcessor后置处理器的后置处理方法:postProcessAfterInitialization(),允许对bean实例进行包装wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}
  • invokeAwareMethods():执行Aware方法,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
// 实现Aware接口的bean在被初始化后,可以取得一些相对应的资源,如BeanFactory、ApplicationContext等,下面就是具体的赋值过程
private void invokeAwareMethods(String beanName, Object bean) {if (bean instanceof Aware) {// 1、如果bean实现了BeanNameAware接口,那么在bean内部可以获取到BeanName属性if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}// 2、如果bean实现了BeanClassLoaderAware接口,那么在bean内部可以获取到BeanClassLoader对象if (bean instanceof BeanClassLoaderAware) {ClassLoader bcl = getBeanClassLoader();if (bcl != null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}// 3、如果bean实现了BeanFactoryAware接口,那么在bean内部可以获取到BeanFactory工厂对象if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}
}
  • applyBeanPostProcessorsBeforeInitialization():执行BeanPostProcessor后置处理器的前置处理方法
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;// 1、获取到当前工厂中注册的所有BeanPostProcessor后置处理器for (BeanPostProcessor processor : getBeanPostProcessors()) {// 2、执行每一个BeanPostProcessor的前置增强方法:postProcessBeforeInitialization()Object current = processor.postProcessBeforeInitialization(result, beanName);if (current == null) {// 3、如果postProcessBeforeInitialization()返回为空,则直接返回,将不会执行后续的BeanPostProcessor后置处理器的增强return result;}// 4、使用增强后的bean current,赋值给result,然后返回result = current;}return result;
}
  • invokeInitMethods():执行初始化方法,包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-method
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {// 1、检查bean是否实现了InitializingBean接口,如果实现了,则需要执行InitializingBean接口的afterPropertiesSet()方法boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isTraceEnabled()) {logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");}// 2、调用InitializingBean接口的afterPropertiesSet()方法if (System.getSecurityManager() != null) {try {AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {((InitializingBean) bean).afterPropertiesSet();return null;}, getAccessControlContext());} catch (PrivilegedActionException pae) {throw pae.getException();}} else {((InitializingBean) bean).afterPropertiesSet();}}// 3、调用用户自定义的初始化方法,比如init-method等if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {// 执行用户自定义的初始化方法invokeCustomInitMethod(beanName, bean, mbd);}}
}
  • applyBeanPostProcessorsAfterInitialization():执行BeanPostProcessor后置处理器的后置处理方法:postProcessAfterInitialization(),允许对bean实例进行包装
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;// 1、获取到工厂中注册的所有BeanPostProcessor后置增强器for (BeanPostProcessor processor : getBeanPostProcessors()) {// 2、执行BeanPostProcessor的后置增强方法postProcessAfterInitialization()Object current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {// 3、如果postProcessAfterInitialization()返回为空,则直接返回,将不会执行后续的BeanPostProcessor后置处理器的增强return result;}// 4、使用增强后的bean current,赋值给result,然后返回result = current;}return result;
}

十、registerDisposableBeanIfNecessary():注册DisposableBean

注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理。

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);// 如果bean的作用域不是prototype,且bean需要在关闭时进行销毁if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {// 如果bean的作用域是singleton,则会注册用于销毁的bean到disposableBeans缓存,执行给定bean的所有销毁工作if (mbd.isSingleton()) {// Register a DisposableBean implementation that performs all destruction// work for the given bean: DestructionAwareBeanPostProcessors,// DisposableBean interface, custom destroy method.registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));} else {// 如果bean的作用域不是prototype、也不是singleton,而是其他作自定义用域的话,则注册一个回调,以在销毁作用域内的指定对象时执行// A bean with a custom scope...Scope scope = this.scopes.get(mbd.getScope());if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");}scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));}}
}public void registerDisposableBean(String beanName, DisposableBean bean) {// 注册用于销毁的bean到disposableBeans缓存synchronized (this.disposableBeans) {// private final Map<String, Object> disposableBeans = new LinkedHashMap<>();this.disposableBeans.put(beanName, bean);}
}

十一、总结

最后,通过一张图总结一下整个IOC容器初始化的过程,读者可以对照着图,仔细分析各部分的代码。

Spring createBean()源码笔记相关推荐

  1. spring aop原理_Spring知识点总结!已整理成142页离线文档(源码笔记+思维导图)...

    写在前面 由于Spring家族的东西很多,一次性写完也不太现实.所以这一次先更新Spring[最核心]的知识点:AOP和IOC 无论是入门还是面试,理解AOP和IOC都是非常重要的.在面试的时候,我没 ...

  2. 【若依】开源框架学习笔记 07 - 登录认证流程(Spring Security 源码)

    文章目录 一.概述 二.登录过程代码实现 三.用户验证流程(Spring Security 源码) 1.处理用户认证逻辑过滤器 `UsernamePasswordAuthenticationFilte ...

  3. 首发,看了这份美团架构师的spring源码笔记后,才发现原来学习的思路都错了

    前言 Spring让我们可以更快,更轻松,更安全地进行Java编程.Spring对速度,简单性和生产率的关注使其成为世界上最受欢迎的Java框架. 像阿里巴巴,亚马逊,微软等在内的所有科技巨头对Spr ...

  4. 狂神Spring Boot 员工管理系统 【源码 + 笔记 + web素材】 超详细整理

    目录 员工管理系统 1.准备工作 1.1.导入资源 1.2.编写pojo层 1.3.编写dao层 2.首页实现 2.1.引入Thymeleaf 2.2.编写MyMvcConfig 2.3.测试首页 3 ...

  5. SpringBoot源码笔记分析

    SpringBoot源码笔记分析 1.基础 1.配置SpringBoot热部署 1.引入依赖 <dependency><groupId>org.springframework. ...

  6. Spring AOP源码解析——AOP动态代理原理和实现方式

    2019独角兽企业重金招聘Python工程师标准>>> Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和 ...

  7. 轻轻松松看懂Spring AOP源码

    轻轻松松看懂Spring AOP源码 https://baijiahao.baidu.com/s?id=1596466083334197175&wfr=spider&for=pc 如果 ...

  8. Spring MVC源码——Servlet WebApplicationContext

    上一篇笔记(Spring MVC源码--Root WebApplicationContext)中记录了下 Root WebApplicationContext 的初始化代码.这一篇来看 Servlet ...

  9. 一步一步手绘Spring AOP运行时序图(Spring AOP 源码分析)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  10. 面试大厂被MyBatis问到“哑口无言”?这份MyBatis源码笔记助你吊打面试官!

    写在前面 随着手机.平板电脑等移动终端的广泛应用,移动互联网时代已经到来.在这个时代里,构建一个高效的平台并提供服务是移动互联网的基础,在众多的网站服务中,使用Java构建网站的不在少数,移动互联网的 ...

最新文章

  1. 重温一遍数据结构之单链表(golang版)
  2. excel只对筛选后的结果单独用公式
  3. 使用Docker虚拟化出一个Centos7操作系统(140、141机器上执行)
  4. think php上传图片,上传 · ThinkPHP5.0完全开发手册 · 看云
  5. 如何为项目和产品提供资源——优化工作时间、激励团队和预算
  6. 在caffe中添加样本扩增的功能
  7. python绘制四边螺旋线代_Python绘制3d螺旋曲线图实例代码
  8. jmeter压力性能测试-多台机器并发请求
  9. PaddlePaddle(2)——数据获取与处理(以CV任务为主)
  10. 软件开发生命周期来说明不同的测试的使用情况
  11. 125w短波通信距离_短波通信在消防应急救援通信中的应用探讨
  12. 老猿Python博客文章目录索引
  13. eNSP不同网段主机互联-static
  14. 各博客平台编辑器使用测评
  15. win rar如何注册破解
  16. ssssssssss
  17. js中的事件委托或是事件代理详解
  18. hdoj 1276 士兵队列训练问题 模拟队列
  19. 消除SDK更新时的“https://dl-ssl.google.com refused”错误
  20. 网页中在线玩圆桌骑士

热门文章

  1. 容器技术Docker K8s 2 云原生容器技术概述
  2. SwiftUI资源列表
  3. 基于PlayTennis数据集的决策树决策分析
  4. android ram压力测试,android用memtester内存压力测试
  5. 2021-08-31Flink 中的核心概念和基础考察
  6. 提交不了_领导嘲讽程序员代码太过整洁,网友:太矫情,这种代码提交不了
  7. bufferedimage设置位深度_深度解读超级推荐自定义推广,快速上手最新推广利器!...
  8. 冒泡、选择、快速、归并、堆排序算法 python实现
  9. 使用 leastsq 对指定函数格式进行最小二乘拟合
  10. POJ - 1458(最长公共子序列,动态规划)