2.2 spring5源码系列 -- ioc加载的整体流程

前端之家收集整理的这篇文章主要介绍了2.2 spring5源码系列 -- ioc加载的整体流程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

之前我们知道了spring ioc的加载过程,具体如下图. 下面我们就来对照下图,看看ioc加载的源代码.

 下面在用装修类比,看看个个组件都是怎么工作的.

 

接下来是源码分析的整体结构图. 对照上面的思路梳理出来的

 

一、源码分析的入口 

通常,我们的入口都是从main方法进入. 这里我们也来定义一个main方法

  1. public class MainStarter {
  2. public static void main(String[] args) {
  3. // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
  4. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStarter.class);
  5. context.scan("package name");
  6. Car car = (Car) context.getBean("car");
  7. System.out.println(car.getName());
  8. context.close();
  9. }
  10. }

 

顺便再来看看还有哪些相关的类

  1. /**
  2. * 这是一个配置类,* 在配置类里面定义了扫描的包路径com.lxl.www.iocbeanlifecicle
  3. * 这是会将这个包下配置了注解的类扫描到ioc容器里面,成为一个成熟的bean
  4. */
  5. @Configuration
  6. @ComponentScan(basePackages = {"com.lxl.www.iocbeanlifecicle"})
  7. public class MainConfig {
  8. }

这个类有一个注解@Configuration,这样这个类会被扫描成bean

还有一个注解@ComponentScan(backPackage = {"com.lxl.www.iocbeanlifecicle"}) 他表示,请扫描com.lxl.www.iocbeanlifecicle包下所有的类.

com.lxl.www.iocbeanlifecicle 这个包下还有哪些类呢? 我们来看看项目结构

 

 

 这是这个包下完整的项目结构. 

下面会逐渐说明,每个类的用途

 

二. 最重要的类beanfactory

我们知道在将一个class加载为bean的过程中beanfactory是最最重要的,那么他是何时被加载的呢?

我们来跟踪一下带有一个参数的构造方法AnnotationConfigApplicationContext

  1. public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
  2. // 进入构造函数,首先调用自身的构造方法this();
  3. // 调用自身的构造方法之前,要先调用父类的构造方法
  4. this();
  5. // retister配置注册
  6. register(componentClasses);
  7. // ioc容器shua新接口--非常重要
  8. refresh();
  9. }

这就是AnnotationConfigApplicationContext初始化的时候做的三件事

第一件事:  this();  //调用自身的无参构造方法. 同时调用父类的构造方法

第二件事: register(componentClasses); // 调用注册器,这里会加载两个BeanDefinitionReader和BeanDefinitionScanner. 这两位的角色是什么呢? 可以回忆一下之前的框架图

第三件事: refresh();  // 这是ioc容器刷新,非常重要. 无论是spring boot还是spring mvc都有这个方法. 这个方法包含了整个spring ioc加载的全生命流程. 也是我们要重点学习的方法

 

下面来看看beanfactory是何时被加载进来的呢?

在初始化方法的时候调用了自身的无参构造函数,在调用自身无参构造函数的时候,同时会调用父类的无参构造函数

  1. public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
      ......
    }

父类是GenericApplicationContext,其无参构造函数就做了一件事

  1. public GenericApplicationContext() {
  2. // 构造了一个beanfactory.
  3. // 在调用GenericApplicationContext父类构造函数,为ApplicationContext spring上下文对象初始化beanfactory
  4. // 为什么初始化的是DefaultListablebeanfactory呢?
  5. // 我们在看beanfactory接口的时候发现DefaultListablebeanfactory是最底层的实现,功能是最全的.
  6. // 查看
  7. this.beanfactory = new DefaultListablebeanfactory();
  8. }

初始化DefaultListablebeanfactory

问题: beanfactory有很多,为什么初始化的时候选择DefaultListablebeanfactory呢?

我们来看看DefaultListablebeanfactory的结构. 快捷键option + command + u --> Java Class Diagrams

 

 

 通过观察,我们发现, DefaultListablebeanfactory实现了各种各样的beanfactory接口,同时还是先了BeanDefinitionRegistry接口. 

也就是说, DefaultListablebeanfactory不仅仅有beanfactory的能力,同时还有BeanDefinitionRegistry的能力. 它的功能是最全的.

所以,我们使用的是一个功能非常强大的类Bean工厂类. 

 

AnnotationConfigApplicationContext继承了GenericApplicationContext,

而 GenericApplicationContext 实现了AnnotationConfigRegistry接口.

所以AnnotationConfigApplicationContext有AnnotationConfigRegistry的能力.

 

三. bean定义读取器AnnotatedBeanDefinitionReader

接着上面,第一步调用的是this(). 也就是AnnotationConfigApplicationContext的无参构造函数. 在这个无参构造函数里一共做了两件事情

  1. public AnnotationConfigApplicationContext() {
  2. /**
  3. * 创建了一个Bean定义的读取器.
  4. * 完成了spring内部BeanDefinition的注册(主要是后置处理器)
  5. * 读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring 的原始类.
  6. */
  7. this.reader = new AnnotatedBeanDefinitionReader(this);
  8. /**
  9. * 创建BeanDefinition扫描器
  10. * 可以用来扫描包或者类,进而转换为bd
  11. *
  12. * Spring默认的扫描包不是这个scanner对象
  13. * 而是自己new的一个ClassPathBeanDefinitionScanner
  14. * Spring在执行工程后置处理器ConfigurationClassPostProcessor时,去扫描包时会new一个ClassPathBeanDefinitionScanner
  15. *
  16. * 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
  17. * 通过调用context.scan("package name");扫描处理配置类
  18. * 扫描
  19. */
  20. this.scanner = new ClassPathBeanDefinitionScanner(this);
  21. }

1. 初始化AnnotatedBeanDefinitionReader.

2. 初始化ClassPathBeanDefinitionScanner

我们先来看看AnnotatedBeanDefinitionReader

 

 

 在这里的描述中,我们知道BeanDefinitionReader是要去扫描配置或者注解,如果理解为销售的话,就是扫描楼盘. 这里面就有我们的潜在用户. 也就是我们需要将其转换为bean的对象. 

那么初始化的时候,AnnotatedBeanDefinitionReader做了什么呢?

重点看这句

  1. public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry,Environment environment) {
  2. Assert.notNull(registry,"BeanDefinitionRegistry must not be null");
  3. Assert.notNull(environment,"Environment must not be null");
  4. this.registry = registry;
  5. this.conditionEvaluator = new ConditionEvaluator(registry,environment,null);
         // 注册注解类型配置的处理器
  6. AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
  7. }

注册注解类型配置的处理器

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

  1.    /**
  2. * Register all relevant annotation post processors in the given registry.
  3. * @param registry the registry to operate on
  4. * @param source the configuration source element (already extracted)
  5. * that this registration was triggered from. May be {@code null}.
  6. * @return a Set of BeanDefinitionHolders,containing all bean definitions
  7. * that have actually been registered by this call
  8. */
  9. public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
  10. BeanDefinitionRegistry registry,@Nullable Object source) {
  11. // 获取beanfactory
  12. DefaultListablebeanfactory beanfactory = unwrapDefaultListablebeanfactory(registry);
  13. /**
  14. * 判断beanfactory中是否有AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver
  15. * 没有则添加
  16. */
  17. if (beanfactory != null) {
  18. if (!(beanfactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
  19. beanfactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
  20. }
  21. if (!(beanfactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
  22. beanfactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
  23. }
  24. }
  25. // BeanDefinitionHolder: 为BeanDefinition设置名字和别名
  26. Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
  27. // 1. 如果registry中没有ConfigurationClassPostProcessor配置类后置处理器,就添加一个
  28. if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  29. RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
  30. def.setSource(source);
  31. // 构建BeanDefinitionHolder,并添加到beanDefs
  32. beanDefs.add(registerPostProcessor(registry,def,CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
  33. }
  34. // 2. 如果rigistry中,没有AutowiredAnnotationBeanPostProcessor Autowired注解bean的后置处理器,则添加一个
  35. if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  36. RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
  37. def.setSource(source);
  38. // 构建BeanDefinitionHolder,AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
  39. }
  40. // Check for JSR-250 support,and if present add the CommonAnnotationBeanPostProcessor.
  41. // 3. 检查对JSR-250的支持,如果rigistry中没有CommonAnnotationBeanPostProcessor通用注解后置处理器,则添加一个
  42. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  43. RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
  44. def.setSource(source);
  45. // 构建BeanDefinitionHolder,COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
  46. }
  47. // Check for JPA support,and if present add the PersistenceAnnotationBeanPostProcessor.
  48. // 4. 检查对jpa的支持,如果不包含internalPersistenceAnnotationProcessor,持久化注解处理器,就添加一个
  49. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  50. RootBeanDefinition def = new RootBeanDefinition();
  51. try {
  52. def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));
  53. }
  54. catch (ClassNotFoundException ex) {
  55. throw new IllegalStateException(
  56. "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,ex);
  57. }
  58. def.setSource(source);
  59. beanDefs.add(registerPostProcessor(registry,PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
  60. }
  61. // 5. 检查对事件监听的支持,如果不包含事件监听处理器internalEventListenerProcessor,就添加一个
  62. if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
  63. RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
  64. def.setSource(source);
  65. beanDefs.add(registerPostProcessor(registry,EVENT_LISTENER_PROCESSOR_BEAN_NAME));
  66. }
  67. // 6. 如果不包含事件监听工厂处理器internalEventListenerFactory,就添加一个
  68. if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
  69. RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
  70. def.setSource(source);
  71. beanDefs.add(registerPostProcessor(registry,EVENT_LISTENER_FACTORY_BEAN_NAME));
  72. }
  73. return beanDefs;
  74. }

在这里注册了6个后置处理器.

 

 

 

四. bean定义扫描器ClassPathBeanDefinitionScanner

 

  1.   public AnnotationConfigApplicationContext() {
  2. /**
  3. * 创建了一个Bean定义的读取器.
  4. * 完成了spring内部BeanDefinition的注册(主要是后置处理器)
  5. * 读取了很多spring自定义的配置(主要是后置处理器). 这些类都是spring 的原始类.
  6. */
  7. this.reader = new AnnotatedBeanDefinitionReader(this);
  8. /**
  9. * 创建BeanDefinition扫描器
  10. * 可以用来扫描包或者类,去扫描包时会new一个ClassPathBeanDefinitionScanner
  11. *
  12. * 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
  13. * 通过调用context.scan("package name");扫描处理配置类
  14. * 扫描
  15. */
  16. this.scanner = new ClassPathBeanDefinitionScanner(this);
  17. }

主要看加粗的部分. 这部分初始化了BeanDefinition扫描器. 这里的这个scanner不是spring默认的扫描包. Spring默认的扫描包不是这个scanner对象,而是自己new的一个ClassPathBeanDefinitionScanner, Spring在执行后置处理器ConfigurationClassPostProcessor时,去扫描包时会new一个ClassPathBeanDefinitionScanner, 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法通过调用context.scan("package name");扫描处理配置类

 比如,我们可以这样使用

  1. public static void main(String[] args) {
  2. // 第一步: 通过AnnotationConfigApplicationContext读取一个配置类
  3. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainStarter.class);
  4. context.scan("package name");
  5. Car car = (Car) context.getBean("car");
  6. System.out.println(car.getName());
  7. context.close();
  8. }

 

首先调用了ClassPathBeanDefinitionScanner(this) 构造方法,然后调用registerDefaultFilter注册摩尔恩的过滤器,这里面默认的过滤器有两种: javax.annotation.ManagedBean 和 javax.inject.Named. 同时隐含的会注册所有带有@Component @Repository @Controller关键字的注解

  1. @SuppressWarnings("unchecked")
  2. protected void registerDefaultFilters() {
  3. this.includeFilters.add(new AnnotationTypeFilter(Component.class));
  4. ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
  5. try {
  6. this.includeFilters.add(new AnnotationTypeFilter(
  7. ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean",cl)),false));
  8. logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
  9. }
  10. catch (ClassNotFoundException ex) {
  11. // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
  12. }
  13. try {
  14. this.includeFilters.add(new AnnotationTypeFilter(
  15. ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named",false));
  16. logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
  17. }
  18. catch (ClassNotFoundException ex) {
  19. // JSR-330 API not available - simply skip.
  20. }
  21. }

 

在ClassPathBeanDefinitionScanner中,有一个非常重要的方法,就是doScan(String ....beanPackages). 用来扫描传入的配置文件.

 

五.  注册配置方法

  1. public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
  2. // 进入构造函数,要先调用父类的构造方法
  3. this();
  4. // register配置注册
  5. register(componentClasses);
  6. // ioc容器shua新接口--非常重要
  7. refresh();
  8. }

这是AnnotationConfigApplicationContext方法的构造函数,里面第二步调用了register()方法

 

 

 

  1.   private <T> void doRegisterBean(Class<T> beanClass,@Nullable String name,@Nullable Class<? extends Annotation>[] qualifiers,@Nullable Supplier<T> supplier,@Nullable BeanDefinitionCustomizer[] customizers) {
  2. // 将入参beanClass构建成AnnotatedGenericBeanDefinition对象
  3. AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
  4. if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
  5. return;
  6. }
  7. abd.setInstanceSupplier(supplier);
  8. ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
  9. abd.setScope(scopeMetadata.getScopeName());
  10. String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd,this.registry));
  11. // 处理通用定义注解
  12. AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
  13. if (qualifiers != null) {
  14. for (Class<? extends Annotation> qualifier : qualifiers) {
  15. if (Primary.class == qualifier) {
  16. abd.setPrimary(true);
  17. }
  18. else if (Lazy.class == qualifier) {
  19. abd.setLazyInit(true);
  20. }
  21. else {
  22. abd.addQualifier(new AutowireCandidateQualifier(qualifier));
  23. }
  24. }
  25. }
  26. if (customizers != null) {
  27. for (BeanDefinitionCustomizer customizer : customizers) {
  28. customizer.customize(abd);
  29. }
  30. }
  31. BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd,beanName);
  32. definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata,definitionHolder,this.registry);
  33. BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder,this.registry);
  34. }

  1. AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);用来加载bean元数据中的注解

    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder,this.registry);用来注册bean定义. 经过一些列的教研,没有问题,然后将其让入到this.beanDefinitionMap.put(beanName,beanDefinition);中
  1. 具体做了哪些工作,可以看看上面的结构图

 六. Refresh() -- spring ioc容器刷新方法

  1. public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
  2. // 进入构造函数,要先调用父类的构造方法
  3. this();
  4. // register配置注册
  5. register(componentClasses);
  6. // ioc容器shua新接口--非常重要
  7. refresh();
  8. }

refresh()方法,spring有很多衍生品,比如spring mvc,spring boot,都有这个方法. refresh()里面定义了spring ioc中bean加载的全过程. 

  1. @Override
  2. public void refresh() throws BeansException,IllegalStateException {
  3. synchronized (this.startupShutdownMonitor) {
  4. // 1. 准备刷新上下文环境
  5. prepareRefresh();
  6. // Tell the subclass to refresh the internal bean factory.
  7. //2. 获取告诉子类初始化bean工厂,不同工厂不同实现
  8. ConfigurableListablebeanfactory beanfactory = obtainFreshbeanfactory();
  9. // Prepare the bean factory for use in this context.
  10. //3. 对bean工厂进行填充属性
  11. preparebeanfactory(beanfactory);
  12. try {
  13. // Allows post-processing of the bean factory in context subclasses.
  14. // 4. 留个子类去实现该接口
  15. postProcessbeanfactory(beanfactory);
  16. // Invoke factory processors registered as beans in the context.
  17. /*
  18. * 调用bean工厂的后置处理器
  19. * 1. 会再次class扫描成BeanDefinition
  20. */
  21. invokebeanfactoryPostProcessors(beanfactory);
  22. // Register bean processors that intercept bean creation.
  23. // 注册bean后置处理器
  24. registerBeanPostProcessors(beanfactory);
  25. // Initialize message source for this context.
  26. // 初始化国际化资源处理器
  27. initMessageSource();
  28. // Initialize event multicaster for this context.
  29. // 创建事件多播放器
  30. initApplicationEventMulticaster();
  31. // Initialize other special beans in specific context subclasses.
  32. // 这个方法通用也是留个子类实现的,spring boot也是从这个方法进行启动
  33. onRefresh();
  34. // Check for listener beans and register them.
  35. // 将事件监听器注册到多播放器上
  36. registerListeners();
  37. // Instantiate all remaining (non-lazy-init) singletons.
  38. // 实例化剩余的单实例bean
  39. /**
  40. * 这个方法就是循环遍历BeanDefinitionMap,调用getBean,去生产bean
  41. */
  42. finishbeanfactoryInitialization(beanfactory);
  43. // Last step: publish corresponding event.
  44. //最后容器刷新 发布刷新时间(spring cloud是从这里启动的 )
  45. finishRefresh();
  46. }
  47. catch (BeansException ex) {
  48. if (logger.isWarnEnabled()) {
  49. logger.warn("Exception encountered during context initialization - " +
  50. "cancelling refresh attempt: " + ex);
  51. }
  52. // Destroy already created singletons to avoid dangling resources.
  53. destroyBeans();
  54. // Reset 'active' flag.
  55. cancelRefresh(ex);
  56. // Propagate exception to caller.
  57. throw ex;
  58. }
  59. finally {
  60. // Reset common introspection caches in Spring's core,since we
  61. // might not ever need Metadata for singleton beans anymore...
  62. resetCommonCaches();
  63. }
  64. }
  65. }

这是refresh()的源码,在refresh()中做了很多很多事情,我们这次主要看和ioc中beanfactory创建bean有关的部分.

 

一个是: invokebeanfactoryPostProcessors(beanfactory);

另一个是: finishbeanfactoryInitialization(beanfactory);

 

6.1 invokebeanfactoryPostProcessors(beanfactory) 调用beanfactory的后置处理器

 在AnnotatedBeanDefinitionReader这里扫描了所有后置处理器,将其解析到beanDefinitionMap,在这里调用后置处理器

 

6.2 finishbeanfactoryInitialization 实例化剩余的单实例bean

 这个方法就是循环遍历BeanDefinitionMap,去生产bean

 

这里第一个是: 冻结配置类,意思是说,我马上就要开始制造bean了,bean配置文件不能再修改了,所以被冻结

原理是有一个变量标记,设为true标记冻结.

  1. @Override
  2. public void freezeConfiguration() {
  3. this.configurationFrozen = true;
  4. this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
  5. }

 

第二个是实例化创建bean

  1. Override
  2. protected Object createBean(String beanName,RootBeanDefinition mbd,@Nullable Object[] args)
  3. throws BeanCreationException {
  4. if (logger.isTraceEnabled()) {
  5. logger.trace("Creating instance of bean '" + beanName + "'");
  6. }
  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已经被解析了
  12. Class<?> resolvedClass = resolveBeanClass(mbd,beanName);
  13. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  14. mbdToUse = new RootBeanDefinition(mbd);
  15. mbdToUse.setBeanClass(resolvedClass);
  16. }
  17. // Prepare method overrides.
  18. try {
  19. /**
  20. * 验证和准备覆盖方法(近在xml方式中)
  21. * lookup-method 和 replace-method
  22. * 这两个配置存放在BeanDefinition中的methodOverrides(仅在XML方式中)
  23. * 在XML方式中,bean实例化的过程中如果检测到存在methodOverrides
  24. * 则会动态的为当前bean生成代理并使用对应的拦截器为bean做增强处理
  25. * 具体的实现我们后续分析. 现在先看mbdtoUse.prepareMethodOverrides()代码
  26. */
  27. mbdToUse.prepareMethodOverrides();
  28. }
  29. catch (BeanDefinitionValidationException ex) {
  30. throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName,"Validation of method overrides Failed",ex);
  31. }
  32. try {
  33. // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  34. /**
  35. * 初始化之前的解析
  36. * 第一次调用bean后置处理器
  37. * 铜鼓bean的后置处理器来进行后置处理生成代理对象,一般情况下在此处不会生成代理对象
  38. * 为什么不能生成代理对象? 不管是我们的JDK还是cglib代理都不会在此处进行代理,因为我们的真实对象没有生成,* 所以在这里不会生成代理对象
  39. * 这一步是aop和事务的关键,因为在这解析我们的aop切面信息进行缓存.
  40. */
  41. Object bean = resolveBeforeInstantiation(beanName,mbdToUse);
  42. if (bean != null) {
  43. return bean;
  44. }
  45. }
  46. catch (Throwable ex) {
  47. throw new BeanCreationException(mbdToUse.getResourceDescription(),"BeanPostProcessor before instantiation of bean Failed",ex);
  48. }
  49. try {
  50. /*
  51. * 执行创建bean,这里就是执行创建bean的三个步骤
  52. * 1. 实例化
  53. * 2. 填充属性,@Autowired @Value
  54. * 3. 初始化 初始化initMethod方法和初始化destroy方法
  55. */
  56. Object beanInstance = doCreateBean(beanName,mbdToUse,args);
  57. if (logger.isTraceEnabled()) {
  58. logger.trace("Finished creating instance of bean '" + beanName + "'");
  59. }
  60. return beanInstance;
  61. }
  62. catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
  63. // A prevIoUsly detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
  64. throw ex;
  65. }
  66. catch (Throwable ex) {
  67. throw new BeanCreationException(
  68. mbdToUse.getResourceDescription(),"Unexpected exception during bean creation",ex);
  69. }
  70. }

 

创建bean的三个步骤 

 

  1. protected Object doCreateBean(final String beanName,final RootBeanDefinition mbd,final @Nullable Object[] args)
  2. throws BeanCreationException {
  3. // Instantiate the bean.
  4. BeanWrapper instanceWrapper = null;
  5. if (mbd.isSingleton()) {
  6. instanceWrapper = this.factorybeanInstanceCache.remove(beanName);
  7. }
  8. if (instanceWrapper == null) {
  9. /**
  10. * 第一步: 实例化
  11. * 这里面的调用链非常深,后面再看
  12. * bean实例化有两种方式
  13. * 1. 使用反射: 使用反射也有两种方式,* a. 通过无参构造函数 (默认的方式)
  14. * 从beanDefinition中可以得到beanClass,* ClassName = BeanDefinition.beanclass
  15. * Class clazz = Class.forName(ClassName);
  16. * clazz.newInstance();
  17. * 这样就可以实例化bean了
  18. *
  19. * b. 通过有参函数.
  20. * ClassName = BeanDefinition.beanclass
  21. * Class clazz = Class.forName(ClassName);
  22. * Constractor con = class.getConstractor(args....)
  23. * con.newInstance();
  24. *
  25. * 2. 使用工厂
  26. * 我们使用@Bean的方式,就是使用的工厂模式,自己控制实例化过程
  27. *
  28. */
  29. instanceWrapper = createBeanInstance(beanName,mbd,args);
  30. }
  31. // 这里使用了装饰器的设计模式
  32. final Object bean = instanceWrapper.getWrappedInstance();
  33. Class<?> beanType = instanceWrapper.getWrappedClass();
  34. if (beanType != NullBean.class) {
  35. mbd.resolvedTargetType = beanType;
  36. }
  37. // Allow post-processors to modify the merged bean definition.
  38. // 允许后置处理器修改已经合并的beanDefinition
  39. synchronized (mbd.postProcessingLock) {
  40. if (!mbd.postProcessed) {
  41. try {
  42. applyMergedBeanDefinitionPostProcessors(mbd,beanType,beanName);
  43. }
  44. catch (Throwable ex) {
  45. throw new BeanCreationException(mbd.getResourceDescription(),"Post-processing of merged bean definition Failed",ex);
  46. }
  47. mbd.postProcessed = true;
  48. }
  49. }
  50. // Eagerly cache singletons to be able to resolve circular references
  51. // even when triggered by lifecycle interfaces like beanfactoryAware.
  52. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  53. isSingletonCurrentlyInCreation(beanName));
  54. if (earlySingletonExposure) {
  55. if (logger.isTraceEnabled()) {
  56. logger.trace("Eagerly caching bean '" + beanName +
  57. "' to allow for resolving potential circular references");
  58. }
  59. addSingletonFactory(beanName,() -> getEarlyBeanReference(beanName,bean));
  60. }
  61. // Initialize the bean instance.
  62. Object exposedObject = bean;
  63. try {
  64. // 第二步:填充属性,给属性赋值(调用set方法) 这里也是调用的后置处理器
  65. populateBean(beanName,instanceWrapper);
  66. // 第三步: 初始化.
  67. exposedObject = initializeBean(beanName,exposedObject,mbd);
  68. }
  69. catch (Throwable ex) {
  70. if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
  71. throw (BeanCreationException) ex;
  72. }
  73. else {
  74. throw new BeanCreationException(
  75. mbd.getResourceDescription(),"Initialization of bean Failed",ex);
  76. }
  77. }
  78. if (earlySingletonExposure) {
  79. Object earlySingletonReference = getSingleton(beanName,false);
  80. if (earlySingletonReference != null) {
  81. if (exposedObject == bean) {
  82. exposedObject = earlySingletonReference;
  83. }
  84. else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
  85. String[] dependentBeans = getDependentBeans(beanName);
  86. Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
  87. for (String dependentBean : dependentBeans) {
  88. if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
  89. actualDependentBeans.add(dependentBean);
  90. }
  91. }
  92. if (!actualDependentBeans.isEmpty()) {
  93. throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +
  94. StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
  95. "] in its raw version as part of a circular reference,but has eventually been " +
  96. "wrapped. This means that said other beans do not use the final version of the " +
  97. "bean. This is often the result of over-eager type matching - consider using " +
  98. "'getBeanNamesForType' with the 'allowEagerInit' flag turned off,for example.");
  99. }
  100. }
  101. }
  102. }
  103. // Register bean as disposable.
  104. try {
  105. registerDisposableBeanIfNecessary(beanName,bean,mbd);
  106. }
  107. catch (BeanDefinitionValidationException ex) {
  108. throw new BeanCreationException(
  109. mbd.getResourceDescription(),"Invalid destruction signature",ex);
  110. }
  111. return exposedObject;
  112. }

 

具体结构如下:

 

 

 

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1gx5pavn3x1pz

猜你在找的Spring相关文章