迄今為止,所接觸到的Bean都是“無知覺”的,就像黑客帝國中機(jī)械工廠里面“養(yǎng)殖”的人類,他們雖然能完成一定的功能,但是根本不知道自己在工廠(BeanFactory)中的代號(id),或者自己是在哪個(gè)工廠(BeanFactory的引用)中沉睡。所以,本節(jié)的目的就是要?jiǎng)?chuàng)造出一個(gè)尼奧一樣的Bean,讓他知道自己在工廠中的id和自己原來躺在哪個(gè)工廠中。
這里,稱之為,Bean對Spring有知覺。
但是有言在先,如果要在Spring容器中做到這兩點(diǎn),當(dāng)然,可以自己通過某些方法實(shí)現(xiàn),代價(jià)是大量冗余代碼,好處是跟Spring解耦。
如果使用Spring提供的接口,好處當(dāng)然減少代碼的規(guī)模,“缺點(diǎn)”(如果算的話)是與Spring耦合。
總之,無論采取那種辦法還是要看實(shí)際需要。
BeanNameAware 讓Bean對Name有知覺
作用:讓Bean獲取自己在BeanFactory配置中的名字(根據(jù)情況是id或者name)。
額外說明:Spring自動(dòng)調(diào)用。并且會(huì)在Spring自身完成Bean配置之后,且在調(diào)用任何Bean生命周期回調(diào)(初始化或者銷毀)方法之前就調(diào)用這個(gè)方法。換言之,在程序中使用BeanFactory.getBean(String beanName)之前,Bean的名字就已經(jīng)設(shè)定好了。所以,程序中可以盡情的使用BeanName而不用擔(dān)心它沒有被初始化。
當(dāng)然,Bean之中一定要有個(gè)String類型變量來保存BeanName的值,這個(gè)是在編寫B(tài)ean代碼時(shí)有程序員手工完成的,而不是通過什么特殊的餓配置。
通常都是為了更好的餓配置Log,但是請注意,不要只是因?yàn)榕浜螸og就把bean那么中添加任何業(yè)務(wù)含義,否則會(huì)讓你自己的類關(guān)聯(lián)到某個(gè)Spring特性上去,而它帶來的好處卻是微不足道的。如果確實(shí)需要Bean帶有某種內(nèi)部名稱,那么最好讓Bean自己實(shí)現(xiàn)某個(gè)方法,例如setName(),然后使用DI給每個(gè)Bean注入一個(gè)名字,這樣技能保持配置Bean的名字仍然能夠簡潔,且你也無需修改自己的配置文件,好讓Bean的名字帶有業(yè)務(wù)含義。
BeanFactoryAware 讓Bean對工廠有知覺
作用:讓Bean獲取配置他們的BeanFactory的引用。
實(shí)現(xiàn):實(shí)現(xiàn)BeanFactoryAware接口,其中只有一個(gè)方法即setFactory(BeanFactory factory)。使用上與BeanNameAware接口無異,只不過BeanFactoryAware注入的是個(gè)工廠,BeanNameAware注入的是個(gè)Bean的名字。
額外說明:雖然原書中并未提及setFactory()方法的調(diào)用時(shí)機(jī),但是可以猜想到,這個(gè)方法可能是在根據(jù)某個(gè)配置文件創(chuàng)建了一個(gè)新工廠之后,Spring才調(diào)用這個(gè)方法,并把BeanFactory注入到Bean中。
讓bean獲取配置自己的工廠之后,當(dāng)然可以在Bean中使用這個(gè)工廠的getBean()方法,但是,實(shí)際上非常不推薦這樣做,因?yàn)榻Y(jié)果是進(jìn)一步加大Bean與Spring的耦合,而且,能通過DI注入進(jìn)來的盡量通過DI來注入。
當(dāng)然,除了查找bean,BeanFactory可以提供大量其他的功能,例如銷毀singleton模式的Bean。
補(bǔ)充說明:
factory.preInstantiateSingletons();方法。preInstantiateSingletons()方法立即實(shí)例化所有的Bean實(shí)例,有必要對這個(gè)方法和Spring加載bean的機(jī)制做個(gè)簡單說明。
方法本身的目的是讓Spring立即處理工廠中所有Bean的定義,并且將這些Bean全部實(shí)例化。因?yàn)镾pring默認(rèn)實(shí)例化Bean的情況下,采用的是lazy機(jī)制,換言之,如果不通過getBean()方法(BeanFactory或者ApplicationContext的方法)獲取Bean的話,那么為了節(jié)省內(nèi)存將不實(shí)例話Bean,只有在Bean被調(diào)用的時(shí)候才實(shí)例化他們。