BeanFactory 它是一個接口,提供了獲取容器中Bean的相關方法。
BeanDefinitionRegistry 它才是IoC的容器,用于存儲、管理所有的Bean對象。
DefaultListableBeanFactory 它是IoC容器的一個具體實現(xiàn),實現(xiàn)了BeanFactory和BeanDefinitionRegistry接口,因此既擁有管理Bean的容器,又擁有訪問Bean的方法。
BeanDefinition 每一個Bean都有一個BeanDefinition與之對應,用于存儲Bean的相關信息:對象的class類型、是否是抽象類、構(gòu)造方法參數(shù)等。 RootBeanDefinition和ChildBeanDefinition是BeanDefinition的兩個主要的實現(xiàn)類。
BeanDefinitionReader 在Spring中,標注Bean的依賴關系有四中方式:
直接在代碼中聲明通過xml文件聲明通過Properties文件聲明通過注解聲明 BeanDefinitionReader接口的作用就是讀取配置文件中的bean信息,把它們解析成BeanDefinition對象,然后注冊到BeanDefinitionRegistry中去。 PropertiesBeanDefinitionReader和XmlBeanDefinitionReader是該接口的兩個實現(xiàn)類,分別用于解析properties和xml格式的配置文件。XmlBeanFactory 它是一個集成了XmlBeanDefinitionReader功能的BeanFactory,用于簡化初始化操作。
容器啟動階段 該階段Spring會使用BeanDefinitionReader加載配置文件,并把所有的bean解析成BeanDefinition對象,并注冊到BeanDefinitionRegistry。
Bean實例化階段 對于BeanFactory容器,當調(diào)用者主動調(diào)用getBean方法或者因存在依賴關系容器隱式調(diào)用getBean時,如果當前Bean尚未初始化,或者bean配置成prototype,就會觸發(fā)Bean實例的初始化。
Spring提供了BeanFactoryPostProcessor這種容器擴展機制,它允許我們在容器啟動完成后、Bean實例化前插入額外的操作。 BeanFactoryPostProcessor提供了三個實現(xiàn)類:
1.PropertyPlaceholderConfigurer 一般情況下,我們并不會將數(shù)據(jù)庫連接信息直接寫死在dataSource這個bean中,而是將它們單獨寫在一個properties文件中,這樣易于修改與閱讀。而bean中使用占位符代替這些屬性值,當容器啟動完成后,在Bean初始化前用properties文件中的值替換占位符,再創(chuàng)建對象。 PropertyPlaceholderConfigurer就能實現(xiàn)這樣的功能。
xml中作如下配置:<bean id="dataSource" class="xxxxxx"> <property name="url"> <value>${jdbc.url}</value> </property> <property name="username"> <value>${jdbc.username}</value> </property></bean>使用properties文件存儲屬性值:jdbc.url=jdbc:MySQL://127.0.0.1:3306jdbc.username=root當容器啟動完成后dataSource的BeanDefinition對象將會被注冊進BeanDefinitionRegistry中,此時BeanDefinition中的屬性值仍然是占位符的形式;接下倆,PropertyPlaceholderConfigurer就會發(fā)揮作用,它會將占位符用properties文件中的屬性值替換掉。接下來bean就可以被正確地創(chuàng)建。
2.PropertyOverrideConfigurer 它的功能與PropertyPlaceholderConfigurer類似,也需要指定一個properties文件,只不過它會用配置文件中設置的那些bean的屬性值替換指定bean的屬性值。
xml中作如下配置:<bean id="dataSource" class="xxxxxx"> <property name="url"> <value>jdbc:mysql://127.0.0.1:3306</value> </property> <property name="username"> <value>chai</value> </property></bean>使用properties文件存儲屬性值:dataSource.url=jsbc:mysql://127.0.0.1:3307dataSource.username=rootPropertyOverrideConfigurer會在容器啟動完畢后、Bean對象創(chuàng)建之前,通過修改BeanDefinition對象,替換指定的屬性值。 properties文件的內(nèi)容必須遵循如下格式:
bean的名字.屬性名=屬性值3.CustomEditorConfigurer 該類用于向Spring容器增添自定義的PropertyEditor對象。
容器啟動結(jié)束后bean創(chuàng)建之前,配置文件中所有的bean都被解析成BeanDefinition對象,該對象中關于bean所有的信息都是String類型的,若要創(chuàng)建bean對象,就需要將這些String類型的信息解析成它們原本的類型。在Spring中,每種類型都有對應一個PropertyEditor類,該類中封裝了String與該類型的轉(zhuǎn)換方法。當然,對于某些類型Spring并未提供相應的PropertyEditor時,我們可以自定義PropertyEditor,并使用CustomEditorConfigurer將其告訴Spring容器,讓它在遇到該類型的時候采用我們自定義的PropertyEditor去解析。
Spring提供的部分PropertyEditor:
StringArrayPropertyEditor 將字符串轉(zhuǎn)換成String[],默認以,分割。ClassEditor 類似于Class.forname(String),將字符串轉(zhuǎn)換成class對象。FileEditor 將字符串轉(zhuǎn)換成File對象。URLEditor 將字符串轉(zhuǎn)換成URL對象。InputStreamEditor 將字符串轉(zhuǎn)換成InputStream對象。LocaleEditor 將字符串轉(zhuǎn)換成Locale對象。PatternEditor 將字符串轉(zhuǎn)換成Pattern對象。以上類型的字符串,Spring會自動將它們轉(zhuǎn)換成原本的類型。而我們自定義的PropertyEditor必須要通過CustomEditorConfigurer將其加入容器。
如何開啟BeanFactoryPostProcessor功能? 1.BeanFactory
// 創(chuàng)建BeanFactory對象ConfigurableListableBeanFactory beanFactory = new XmlBeanFactory( new ClassPathResource("xxx") );// 創(chuàng)建BeanFactoryPostProcessor對象PropertyPlaceholderConfigurer processor = new PropertyPlaceholderConfigurer();// 設置properties文件的位置processor.setLocation("xxx");// 將其傳遞給beanFactoryprocessor.postProcessBeanFactory(beanFactory);2.ApplicationContext ApplicationContext會自動檢測配置文件中出現(xiàn)的BeanFactoryPostProcessor,因此只需要在配置文件中聲明所使用的BeanFactoryPostProcessor即可。
<bean class="xxxxx.PropertyPlaceholderConfigurer"> <property> <list> <value>properties文件路徑</value> </list> </property></bean>新聞熱點
疑難解答