spring加载顺序
因為項目需求,要實現自定義注解然后通過spring掃描注解并放入緩存,我想到了BeanDefinitionRegistryPostProcessor接口,通過實現?BeanDefinitionRegistryPostProcessor接口postProcessBeanFactory方法實現,因為這個方法的入參postProcessBeanFactory可以得到所有已注入spring的bean,然后獲得自定義注解修飾的bean。到這一切正常,但是我發現在操作的時候屬性配置${name}沒有被加載到bean當中,這是什么原因?
不得不說下spring配置文件的加載順序,當使用spring配置文件時,首先加載bean然后加載import進入spring的bean,當然可以再web.xml中添加配置文件,這時按順序加載。
我的配置文件讀取不到,不得不說下BeanDefinitionRegistryPostProcessor接口,他是在bean定義之后,實例化之前執行的接口,Spring 框架會根據配置,過濾出 BeanDefinitionRegistryPostProcessor 類型的 Bean 定義,并通過 Spring 框架生成其對應的 Bean 對象(如 ConfigurationClassPostProcessor 實例)。結合 Spring 上下文源碼可知這個對象是一個 processor 類型工具類,Spring 容器會在實例化開發人員所定義的 Bean 前先調用該 processor 的 postProcessBeanDefinitionRegistry(...) 方法。這時他也影響了PropertyPlaceholderConfigurer所加載的properties,在其中操作時占用了properties,這時其他需要properties的bean沒有完成初始化,也就是properties沒有被寫入到bean當中,所以就導致${name}沒有被執行。
這種解決辦法就在于在postProcessBeanDefinitionRegistry方法不延緩執行時間而是另起線程對configurableListableBeanFactory進行處理。這樣不影響bean的實例化。
public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) {
Set<String> beanNames = new LinkedHashSet<String>(getBeanDefinitionCount());
beanNames.addAll(Arrays.asList(getBeanDefinitionNames()));
beanNames.addAll(Arrays.asList(getSingletonNames()));
Map<String, Object> results = new LinkedHashMap<String, Object>();
for (String beanName : beanNames) {
if (findAnnotationOnBean(beanName, annotationType) != null) {
results.put(beanName, getBean(beanName));
}
}
return results;
}//源碼中對注解bean的獲取。這里get方法并沒有對configurableListableBeanFactory進行修改。所以不會是改變了它導致properties的處理失敗。
因為postProcessBeanFactory是void方法,所以一定是并發執行,只是執行順序會快一些,這是如果延緩了處理時間,導致后面bean的實例化${name}出問題也就情有可原了。
。。PropertyPlaceholderConfigurer其實也實現了BeanDefinitionRegistryPostProcessor接口。但是執行順序是在前面的,但是它這是并沒有初始化。
但是這個延緩,我總感覺過于牽強!但是確實沒有對它進行操作。
看到的提提意見,歡迎指出錯誤~
總結
以上是生活随笔為你收集整理的spring加载顺序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下文件操作
- 下一篇: 搭建gitlab服务器