整体过程

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean

  1. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  2. throws BeanCreationException {
  3. if (logger.isTraceEnabled()) {
  4. logger.trace("Creating instance of bean '" + beanName + "'");
  5. }
  6. // mbd
  7. RootBeanDefinition mbdToUse = mbd;
  8. // Make sure bean class is actually resolved at this point, and
  9. // clone the bean definition in case of a dynamically resolved Class
  10. // which cannot be stored in the shared merged bean definition.
  11. // 得到bean的Class对象
  12. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  13. // 通过resolveBeanClass操作后,mbd.hasBeanClass()==ture
  14. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  15. mbdToUse = new RootBeanDefinition(mbd);
  16. mbdToUse.setBeanClass(resolvedClass);
  17. }
  18. // Prepare method overrides.
  19. try {
  20. // 准备方法的重写,这块主要处理方法一些注入问题
  21. // https://docs.spring.io/spring-framework/docs/5.2.22.RELEASE/
  22. // spring-framework-reference/core.html#beans-factory-lookup-method-injection
  23. mbdToUse.prepareMethodOverrides();
  24. } catch (BeanDefinitionValidationException ex) {
  25. throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
  26. beanName, "Validation of method overrides failed", ex);
  27. }
  28. try {
  29. // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  30. // 可以通过BeanPostProcessors返回其代理对象
  31. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  32. if (bean != null) {
  33. return bean;
  34. }
  35. } catch (Throwable ex) {
  36. throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
  37. "BeanPostProcessor before instantiation of bean failed", ex);
  38. }
  39. // 没有特殊情况下的创建对象
  40. try {
  41. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  42. if (logger.isTraceEnabled()) {
  43. logger.trace("Finished creating instance of bean '" + beanName + "'");
  44. }
  45. return beanInstance;
  46. } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
  47. // A previously detected exception with proper bean creation context already,
  48. // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
  49. throw ex;
  50. } catch (Throwable ex) {
  51. throw new BeanCreationException(
  52. mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
  53. }
  54. }

执行过程:

  1. 解析 Class;
  2. override 属性进行标记及验证;
  3. 解析指定bean是否存在初始化前的短路操作,可以提前生成代理对象;
  4. 创建 bean;

    resolveBeanClass

    这块代码的作用:获取 mbd 配置的 bean 类名,将 bean 类名解析为 Class 对象,并将解析后的 Class 对象缓存以便后续复用。

开始

  1. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  2. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  3. mbdToUse = new RootBeanDefinition(mbd);
  4. mbdToUse.setBeanClass(resolvedClass);
  5. }

来到方法

  1. protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
  2. throws CannotLoadBeanClassException {
  3. try {
  4. // 如果定义了beanClass直接返回,通常初始化的时候是没有的
  5. if (mbd.hasBeanClass()) {
  6. return mbd.getBeanClass();
  7. }
  8. // 安全管理器的特权处理
  9. if (System.getSecurityManager() != null) {
  10. return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
  11. () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
  12. }
  13. // 其他情况,也就是大部分的情况
  14. else {
  15. return doResolveBeanClass(mbd, typesToMatch);
  16. }
  17. }
  18. catch (PrivilegedActionException pae) {
  19. ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
  20. throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
  21. }
  22. catch (ClassNotFoundException ex) {
  23. throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
  24. }
  25. catch (LinkageError err) {
  26. throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
  27. }
  28. }

来到方法

  1. @Nullable
  2. private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
  3. throws ClassNotFoundException {
  4. // 得到加载该bean的类加载器
  5. ClassLoader beanClassLoader = getBeanClassLoader();
  6. // 指定动态加载器
  7. ClassLoader dynamicLoader = beanClassLoader;
  8. // 表示mdb的配置的bean类名需要重新被dynamicLoader加载的标记,默认不需要
  9. boolean freshResolve = false;
  10. // 是否有匹配的类型
  11. if (!ObjectUtils.isEmpty(typesToMatch)) {
  12. // When just doing type checks (i.e. not creating an actual instance yet),
  13. // use the specified temporary class loader (e.g. in a weaving scenario).
  14. ClassLoader tempClassLoader = getTempClassLoader();
  15. if (tempClassLoader != null) {
  16. dynamicLoader = tempClassLoader;
  17. freshResolve = true;
  18. if (tempClassLoader instanceof DecoratingClassLoader) {
  19. DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
  20. for (Class<?> typeToMatch : typesToMatch) {
  21. dcl.excludeClass(typeToMatch.getName());
  22. }
  23. }
  24. }
  25. }
  26. // 得到类名称
  27. String className = mbd.getBeanClassName();
  28. if (className != null) {
  29. // 评估beanDefinition中包含的className,如果className是可解析表达式,会对其进行解析,否则直接返回className:
  30. Object evaluated = evaluateBeanDefinitionString(className, mbd);
  31. // 如果解析后的名称和className不一样
  32. if (!className.equals(evaluated)) {
  33. // A dynamically resolved expression, supported as of 4.2...
  34. if (evaluated instanceof Class) {
  35. // 如果是Class的实例就直接返回
  36. return (Class<?>) evaluated;
  37. }
  38. else if (evaluated instanceof String) {
  39. // 如果是名称字符串,evaluated作为ClassName
  40. className = (String) evaluated;
  41. // 让dynamicLoader重新加载
  42. freshResolve = true;
  43. }
  44. else {
  45. // 否则异常
  46. throw new IllegalStateException("Invalid class name expression result: " + evaluated);
  47. }
  48. }
  49. // 如果mdb的配置的bean类名需要重新被dynameicLoader加载
  50. if (freshResolve) {
  51. // When resolving against a temporary class loader, exit early in order
  52. // to avoid storing the resolved Class in the bean definition.
  53. if (dynamicLoader != null) {
  54. try {
  55. // 加载得到Class对象
  56. return dynamicLoader.loadClass(className);
  57. }
  58. catch (ClassNotFoundException ex) {
  59. if (logger.isTraceEnabled()) {
  60. logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
  61. }
  62. }
  63. }
  64. // 加载得到Class对象
  65. return ClassUtils.forName(className, dynamicLoader);
  66. }
  67. }
  68. // 到这里表示,评估后的Class名称和className一样。
  69. // 使用classLoader加载当前BeanDefinitiond对象所配置的Bean类名的Class对象
  70. // Resolve regularly, caching the result in the BeanDefinition...
  71. return mbd.resolveBeanClass(beanClassLoader);
  72. }

prepareMethodOverrides()

https://docs.spring.io/spring-framework/docs/5.2.22.RELEASE/spring-framework-reference/core.html#beans-factory-lookup-method-injection
这块主要处理的配置文件中的 lookup-method 和 replace-method 这样的属性。
见:
解析 lookup-method
解析 replaced-method

  1. // Prepare method overrides.
  2. try {
  3. // 准备方法的重写,这块主要处理方法一些注入问题
  4. mbdToUse.prepareMethodOverrides();
  5. }
  6. catch (BeanDefinitionValidationException ex) {
  7. throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
  8. beanName, "Validation of method overrides failed", ex);
  9. }

来到方法

  1. public void prepareMethodOverrides() throws BeanDefinitionValidationException {
  2. // Check that lookup methods exist and determine their overloaded status.
  3. if (hasMethodOverrides()) {
  4. getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
  5. }
  6. }

来到方法

  1. protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
  2. int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
  3. if (count == 0) {
  4. throw new BeanDefinitionValidationException(
  5. "Invalid method override: no method with name '" + mo.getMethodName() +
  6. "' on class [" + getBeanClassName() + "]");
  7. }
  8. else if (count == 1) {
  9. // Mark override as not overloaded, to avoid the overhead of arg type checking.
  10. mo.setOverloaded(false);
  11. }
  12. }

在 Spring 配置中存在 lookup-method 和 replace-method 两个配置功能,而这两个配置的加载其实就是将配置统一存放在BeanDefinition 中的 methodOverrides 属性里,这两个功能实现原理其实是在 bean实例化的时候如果检测到存在 methodOverrides 属性,会动态地为当前 bean 生成代理并使用对应的拦截器为 bean 做增强处理。
对于方法的匹配来讲,如果一个类中存在若干个重载方法,那么在函数调用及增强的时候还需要根据参数类型进行匹配,来最终确认当前调用的到底是哪个函数。在这里将一部分匹配工作完成了,如果当前类中的方法只有一个,那么就设置重载该方法没有被重载,这样在后续调用的时候便可以直接使用找到方法,而不需要进行方法的参数匹配验证了,而且还可以提前对方法存在性进行验证,正可谓一箭雕。

resolveBeforeInstantiation(beanName, mbdToUse)

这个阶段如果满足条件,就可以直接产生代理对象。我们熟知的 AOP 功能就是基于这里的判断的。

  1. try {
  2. // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  3. // 可以通过BeanPostProcessors返回其代理对象
  4. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  5. if (bean != null) {
  6. return bean;
  7. }
  8. }

来到方法 resolveBeforeInstantiation.
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

  1. protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  2. Object bean = null;
  3. // 如果bean已经产生那么mbd.beforeInstantiationResolved=true
  4. if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
  5. // Make sure bean class is actually resolved at this point.
  6. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  7. // 获取目标对象的Class对象
  8. Class<?> targetType = determineTargetType(beanName, mbd);
  9. if (targetType != null) {
  10. // 执行bean初始化前置处理器
  11. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
  12. if (bean != null) {
  13. // 如果产生了对象,那么继续执行初始化后处理器
  14. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
  15. }
  16. }
  17. }
  18. mbd.beforeInstantiationResolved = (bean != null);
  19. }
  20. return bean;
  21. }

实例化前处理器

实例化前的处理器,bean 的实例化前调用,也就是将 AbsractBeanDefinition 转换为 BeanWrapper 前的处理。这个时候可以修改 BeanDefinition,那么我们得到的 bean 可能就是经过修改后的 bean 。
进入方法 applyBeanPostProcessorsBeforeInstantiation.
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation

  1. protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
  2. for (BeanPostProcessor bp : getBeanPostProcessors()) {
  3. // 判断InstantiationAwareBeanPostProcessor的实例
  4. if (bp instanceof InstantiationAwareBeanPostProcessor) {
  5. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  6. Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
  7. if (result != null) {
  8. return result;
  9. }
  10. }
  11. }
  12. return null;
  13. }

那么 InstantiationAwareBeanPostProcessor 的实例就会继续执行 postProcessBeforeInstantiation 方法。
比如我们后创建 AOP 代理的 AbstractAutoProxyCreator 。
可以看出,如果提供了自定义 TargetSource ,那么这个前置处理器就直接返回了代理对象。

  1. public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
  2. // 获取缓存的key,普通bean返回beanName,FactoryBean返回$beanName
  3. Object cacheKey = getCacheKey(beanClass, beanName);
  4. // 判断bean不是空,或者 targetSourcedBeans 不包含该 bean
  5. if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
  6. // 如果advisedBeans包含
  7. if (this.advisedBeans.containsKey(cacheKey)) {
  8. return null;
  9. }
  10. // 如果是aop相关的基础类,或者是应该跳过不处理的类
  11. if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
  12. // 加入缓存advisedBeans,表示已经处理完毕,不需要代理
  13. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  14. return null;
  15. }
  16. }
  17. // Create proxy here if we have a custom TargetSource.
  18. // Suppresses unnecessary default instantiation of the target bean:
  19. // The TargetSource will handle target instances in a custom fashion.
  20. // 获取自定义 TargetSource
  21. TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
  22. if (targetSource != null) {
  23. if (StringUtils.hasLength(beanName)) {
  24. // 不为空加入缓存
  25. this.targetSourcedBeans.add(beanName);
  26. }
  27. // 创建代理对象
  28. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
  29. Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
  30. this.proxyTypes.put(cacheKey, proxy.getClass());
  31. return proxy;
  32. }
  33. return null;
  34. }

实例化后处理器

Spring 中的规则是在 bean 的初始化后尽可能保证将注册的后处理器的 postProcessAfterInitialization 方法应用到该 bean中,因为如果返回的bean不为空,那么便不会再次经历普通 bean 的创建过程,所以只能在这里应用后处理器的 postProcessAfterInitialization 方法。

  1. @Override
  2. public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  3. throws BeansException {
  4. Object result = existingBean;
  5. for (BeanPostProcessor processor : getBeanPostProcessors()) {
  6. Object current = processor.postProcessAfterInitialization(result, beanName);
  7. if (current == null) {
  8. return result;
  9. }
  10. result = current;
  11. }
  12. return result;
  13. }

doCreateBean

如果上面的前置处理器resolveBeforeInstantiation没有产生代理对象的话,那么接下来就开始创建对象了。
进入下一个阶段 doCreateBean。

  1. try {
  2. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  3. if (logger.isTraceEnabled()) {
  4. logger.trace("Finished creating instance of bean '" + beanName + "'");
  5. }
  6. return beanInstance;
  7. } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
  8. // A previously detected exception with proper bean creation context already,
  9. // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
  10. throw ex;
  11. } catch (Throwable ex) {
  12. throw new BeanCreationException(
  13. mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
  14. }