new ClassPathXmlApplicationContext("spring.xml");IOC容器初始化过程

new ClassPathXmlApplicationContext(“spring.xml”);

创建解析器setConfigLocations(configLocations);

configLocations=spring.xml

refresh()

1、为容器初始化做准备prepareRefresh();

2、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();解析spring.xml配置文件,封装所有对象为BeanDefinition对象

  • 1、创建BeanFactory对象

  • 2、xml解析,循环beans标签下所有子标签,循环解析-》

    • 标签是DefaultNamespace,调用默认标签解析方法

      • 解析import标签
      • alias
      • bean
      • beans
    • 标签不是默认namesapce,调用自定义标签解析方法

      • 1、读取spring中所有jar包里面的 "META-INF/spring.handlers文件,建立namespaceURI与handler的映射关系

      • 2、根据标签NamespaceURI,找到对应的标签处理handler,返回这个handler

      • 3、实例化处理标签的handler,调用它的init()方法,建立namespaceURI下所有标签的与其处理类的映射关系,比如:context命令空间下有context:component-scancontext:annotation-configcontext:property-placeholder等标签,建立这些标签与处理类的映射关系,key为:component-scan,annotation-config,property-placeholder等

      • 4、调用标签处理类handler.parse()方法

        • 1、获取这个标签"冒号"后面的部分,找到它的处理类

        • 2、调用处理类的parse方法,以comtext:component-scan标签为例,它的处理类为:ComponentScanBeanDefinitionParser

          • 1、读取它的base-package属性

          • 2、创建扫描器ClassPathBeanDefinitionScanner

          • 3、扫描并把扫描的类封装成beanDefinition对象–》调用scanner.doScan(basePackages),

          • 4、如果这个标签有annotation-config属性,那么注册几个比较重要的BeanPostProcessor–》AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);AutowiredAnnotationBeanPostProcessor
            ConfigurationClassPostProcessor,
            CommonAnnotationBeanPostProcessor这几个重要的postProcessor都是在这里的

            AutowiredAnnotationBeanPostProcessor
            ConfigurationClassPostProcessor,
            CommonAnnotationBeanPostProcessor这几个重要的postProcessor都是在这里的

  • 3、把解析出来的xml标签封装成BeanDefinition对象

3、prepareBeanFactory(beanFactory);给beanFactory设置一些属性值

4、postProcessBeanFactory,预留方法,暂无实现

5、invokeBeanFactoryPostProcessors(beanFactory);

  • 1、获取实现了BeanDefinitionRegistryPostProcessor接口的BeanDefinition对象
  • 2、通过getBean方法将其实例化
  • 3、加入到list中排序
  • 4、循环调用它的postProcessBeanDefinitionRegistry方法,对bean动态增删改
  • 5、循环调用postProcessBeanFactory方法

6、registerBeanPostProcessors(beanFactory);把实现了BeanPostProcessor接口的类实例化,并且加入到BeanFactory中

  • 1、获取所有实现BeanPostProcessor接口的beanName
  • 2、根据优级顺序用getBean方法实例化这些beanPostProcessor
  • 3、将实例化后的beanPostProcessor对象,注册到BeanFactory中

7、initMessageSource();国际化

8、initApplicationEventMulticaster();初始化事件管理类

9、onRefresh();这个方法是用来做内嵌tomcat启动的

10、registerListeners()往事件管理类中注册事件类

11、finishBeanFactoryInitialization(beanFactory);bean实例化过程、ioc、Aop的入口–>循环所有单例beanDefinition对象创建bean

  • 从缓存中获取–》从一级缓存中获取;一缓存没有&bean正在创建–》从二级缓存中获取;二级缓存中没有–》从三级缓存中获取(三级缓存中存放的是一个策略(即:一个方法),如果该对象是代理对象,那么代理对象将会在这里创建)—》三级缓存获取成功–》加放到二级缓存并删除三级缓存;若缓存中可以获取直接返回

  • 创建单例bean–>getSingleton 方法

    • 把beanName添加到singletonsCurrentlyInCreation Set容器中,在这个集合里面的bean都是正在实例化的bean–》beforeSingletonCreation(beanName);

    • createBean()方法

      • 1、创建实例–》createBeanInstance–》调用FactoryMethodName返回(@Bean注解就是通过这个方式实例化的);有@Autowired注解的构造函数返回,无参构造方法返回

      • 2、收集bean中@PostConstruct,@PreDestroy,@Resource,@Autowired,@Value注解的属性、方法–》applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

        CommonAnnotationBeanPostProcessor 支持了@PostConstruct,@PreDestroy,@Resource注解
        AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value注解
        这里是BeanPostProcessor接口的典型运用

        • 循环所有beanPostProcess,判断实现了MergedBeanDefinitionPostProcessor接口的postProcess,调用–》postProcessMergedBeanDefinition()方法,这里说明一下CommonAnnotationBeanPostProcessor和AutowiredAnnotationBeanPostProcessor的调用

          CommonAnnotationBeanPostProcessor和AutowiredAnnotationBeanPostProcessor这2个postProcessor是在扫描spring.xml配置文件,解析context:annotation-config/注解注入到IOC的

          • 1、CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()

            • 构造方法中设置了:initAnnotationType=PostConstruct.class;destroyAnnotationType=PreDestroy.class;ignoredResourceTypes=javax.xml.ws.WebServiceContext; ignoreResourceType(“javax.xml.ws.WebServiceContext”);
              }

              public CommonAnnotationBeanPostProcessor() {
              setOrder(Ordered.LOWEST_PRECEDENCE - 3); setInitAnnotationType(PostConstruct.class); setDestroyAnnotationType(PreDestroy.class); ignoreResourceType(“javax.xml.ws.WebServiceContext”);
              }

            • 收集bean的所有方法上有@PostConstruct @PreDestroy注解的方法

              super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);

            • 收集属性和方法上面是否有@Resource注解,如果有则收集起来封装成对象

              InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);

          • 2、AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()

      • 3、是否单例&是否允许提前暴露&循环依赖—》加入到三级缓存–》addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));加入三级缓存的是一个方法,当从三级缓存中取对象时就会调用这个方法获取对象

      • 4、对bean的所有属性进行依赖注入–》populateBean(beanName, mbd, instanceWrapper);

        • autowireByName(beanName, mbd, bw, newPvs);

        • autowireByType(beanName, mbd, bw, newPvs);

        • 注入bean上带有@AutoWried注解属性、方法–》通过getBean()方法获取实例;注入bean上带有@Resource注解的属方法–》通过getBean()方法获取实例;—》循环所有postProcessor,获取实现InstantiationAwareBeanPostProcessor接口的postProcessor,调用postProcessProperties方法

          前面收集了bean中所有带有@AutoWried @Resource注解的属性、方法,这里对收集的属性和方法注入

      • 5、调用初始化方法–》initializeBean(beanName, exposedObject, mbd);

        在bean调用完构造方法并完成属性依赖注入后,如果需要返回代理对象,那么AOP生成代理对象就是在这里实现的

        • 调用Aware方法

        • 对类中某些特殊方法的调用,比如@PostConstruct,Aware接口–》循环所有BeanPostProcessor—>调用它的postProcessBeforeInitialization方法,这里说明几个postProcessor

          • 1、ApplicationContextAwareProcessor 对某个Aware接口方法的调用
          • 2、InitDestroyAnnotationBeanPostProcessor @PostConstruct注解方法的调用
          • 3、ImportAwareBeanPostProcessor 对ImportAware类型实例setImportMetadata调用
        • 调用实现了InitializingBean接口的方法afterPropertiesSet

        • 生成代理实例–》applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

          • 查找这个bean的切面advice–》getAdvicesAndAdvisorsForBean

            • 1、找到候选的切面–》findEligibleAdvisors

              • 收集带有@Aspect注解的类—》super.findCandidateAdvisors();

              • 创建候选的切面–》this.aspectJAdvisorsBuilder.buildAspectJAdvisors()

                • 获取spring容器中的所有bean的名称BeanName
                • 循环所有beanName,判断类上是否有@Aspect注解
                • 取有@Aspect注解的类Class
                • 循环@Aspect注解类中没有@Pointcut注解的方法(也就是带有@Before@Around@After注解的通知方法)
                • 获取pointCut对象,结合pointCut和通知方法–》生成切面对象Advisor
            • 2、获取所有作用在当前beanClass上的切面–>findAdvisorsThatCanApply

          • 如果有切面advice,那么生成代理对象—》createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

    • bean创建完成后singletonsCurrentlyInCreation要删除该bean–》afterSingletonCreation(beanName);

    • 创建对象成功时,把对象缓存到singletonObjects缓存中,bean创建完成时放入一级缓存,并删除二级缓存和三级缓存—》addSingleton(beanName, singletonObject);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值