spring 整體過程(一)
一、流程圖
二、入口
在Spring中實現控制反轉的是IoC容器,實現方法是依賴注入DI(Dependency Injection,DI),整個過程必然存在一個入口,可以是xml檔案,也可以是純註解,也可以是混合使用。
1)使用xml
ApplicationContext context = new ClassPathXmlApplicationContext("myBean.xml"); MyBean myBean = context.getBean("myBean", MyBean.class); myBean.getMethod("zhangsan",1);
2)使用註解
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.register(StartConfig.class); applicationContext.refresh(); MyBean myBean = context.getBean("myBean", MyBean.class); myBean.getMethod("zhangsan",1);
3)spring boot
SpringApplication.run(StartConfig.class, args);
2)和3)都是註解掃描,註解來自於StartConfig.class,在BeanFactoryPostProcessor階段會解析,解析所有掃描到Bean
三、AbstractApplicationContext上下文
是 ApplicationContext 的抽象實現類,該抽象類實現應用上下文的一些具體操作,提供refresh()方法完成IOC整個流程,在這個過程中建立了BeanFactory,記錄了容器的狀態。其子類實現了對BeanFactory的獲取,可以操作Bean。
四、BeanFactoryPostProcessor
取出BeanDefinition中所有實現了BeanFactoryPostProcessor
五、BeanFactory
最重要的實現類DefaultListableBeanFactory,管理Bean的整個生命週期,從準備->建立->使用->銷燬,提供所有的方法。在BeanFatory中有五個重要屬性:
beanDefinitionMap:存放了Bean的定義資訊,為Bean的建立提供必要資訊
beanDefinitionNames:在建立過程中,迴圈遍歷該集合,依次建立
singletonObjects:存放了已經完成的單例Bean物件
earlySingletonObjects:存放未完成屬性複製的物件,但是被其他物件應用,並賦值的物件。例如:物件A建立過程中注入了B物件,而B物件未建立,這時需要放下A物件去建立B物件,而B物件也引用了A物件,這時會將三級快取中的A物件取出,判斷是否實現AOP,並放入二級快取。
singletonFactories:在物件例項化後,先將lambda表示式存放其中。作為臨時存放。
六、BeanPostProcessor
在使用之前已將所有繼承BeanPostProcessor的Bean建立完成,這些Bean對其他所有普通Bean起作用,符合條件的會執行提供postProcessBeforeInitialization方法和postProcessAfterInitialization方法,攔截了Bean物件初始化之前和初始化之後,完成這個過程後,將Bean物件返會儲存在一級快取中,將二級三級快取刪除。
其中代理類:AspectJAwareAdvisorAutoProxyCreator 或AnnotationAwareAspectJAutoProxyCreator完成了對物件的代理。
七、AOP執行流程
在postProcessAfterInitialization中完成了對Bean的動態代理,這時候代理物件存放在一級快取中,代理Bean中包含兩個重要屬性:MethodInterceptor方法攔截器和CallBack陣列,陣列的第一位是MethodInterceptor,代理物件繼承了父類所有屬性。
當在代理類中對方法的呼叫會執行DynamicAdvisedInterceptor.intercept(),然後對所有advice做篩選,選出符合規則的,通過責任鏈模式依次呼叫方法執行。