我們在之前的文章分析裡已經知道AnnotationConfigServletWebServerApplicationContext在初始化時會實例化一些後置處理器,其中就包括CommonAnnotationBeanPostProcessor處理器,通過之前我們分析@Autowired注解解析流程知道比較關鍵的兩個流程是通過MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()對需要處理的注解進行解析并封裝成InjectionMetadata,然後通過InstantiationAwareBeanPostProcessor.postProcessProperties()方法對InjectionMetadata進行處理,把相應的對象或value找到并填充到屬性中。而CommonAnnotationBeanPostProcessor
跟AutowiredAnnotationBeanPostProcessor繼承體系是一樣的,流程也差不多,隻是在處理細節上稍微有一些區别。
CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition方法
首先調了父類的postProcessMergedBeanDefinition方法,而他的父類是InitDestroyAnnotationBeanPostProcessor,所以先看父類的實現邏輯:
InitDestroyAnnotationBeanPostProcessor.InitDestroyAnnotationBeanPostProcessor方法
代碼結構幾乎是一樣的,那麼我們重點關注的是InitDestroyAnnotationBeanPostProcessor處理的是哪些注解以及在什麼時候開始注解邏輯。
調用細節這裡就不多說了,跟@Autowired流程一樣,從buildLifecycleMetadata方法可以看出:主要是解析initAnnotationType和destroyAnnotationType兩個注解,然後封裝成LifecycleElement和LifecycleMetadata,需要注意的是被修飾的方法必須是無參方法,那麼initAnnotationType和destroyAnnotationType具體代表是哪兩個注解呢
initAnnotationType和destroyAnnotationType具體代表是哪兩個注解呢
從CommonAnnotationBeanPostProcessor的構造方法可以看出,initAnnotationType就是@PostConstruct注解,destroyAnnotationType就是@PreDestroy注解。initAnnotationType和destroyAnnotationType這兩個注解的含義以及被這兩個注解的解析過程已經了解了,那麼什麼時候對封裝後的LifecycleElement和LifecycleMetadata進行處理呢?
LifecycleElement和LifecycleMetadata處理入口以及流程這個流程就要回到bean的實例化流程裡:通過doCreateBean方法對bean實例化時會先用無參構造器或工廠方法進行實例化類,然後用populateBean方法對實例化對象進行屬性的填充,填充完之後用initializeBean方法對bean實例化時需要調用的一些初始化方法進行最後的調用,然後就算實例化完成了,在就注冊了一些bean銷毀時調用的後置處理器(DestructionAwareBeanPostProcessor)。而我們的@PostConstruct就是在initializeBean方法中處理,@PreDestroy在bean銷毀時DestructionAwareBeanPostProcessor.postProcessBeforeDestruction方法中處理。
initializeBean方法處理@PostConstruct
而我們的@PostConstruct就是在BeanPostProcessor.postProcessBeforeInitialization()方法中被處理。
InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization()方法
可以看到實際上就是使用了反射調用了@PostConstruct修飾的方法。
InitDestroyAnnotationBeanPostProcessor.postProcessBeforeDestruction()方法
可以看到實際上就是使用了反射調用了@PreDestroy修飾的方法。
至此,InitDestroyAnnotationBeanPostProcessor對于@PostConstruct和@PreDestroy的處理邏輯就處理完了。我們接着看CommonAnnotationBeanPostProcessor中的postProcessMergedBeanDefinition()邏輯。
CommonAnnotationBeanPostProcessor.findResourceMetadata方法
resourceAnnotationTypes這個屬性是使用下面這個static代碼塊初始化的
而@Resource注解會被封裝成ResourceElement對象。
ResourceElement.getResourceToInject方法
可以看到@Resource默認是name進行注入,如果@Resource設置了name則以設置的為準否則以屬性的變量名為準。
總結:更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!