之前和打倒小日本做項目的時候,用seam,曾經定過一條規則,Service/Manager/DAO這個層面上由于元件數量不是特别多,是以元件命名不需要空間字首,但是對于action層面的元件,由于可能很多,是以按功能子產品劃分命名空間,例如:
@Compoenent("treasure.selector"),@Component("store.main")等等,在Seam的支援下,在頁面上寫表達式語言的時候,沒有任何問題,例如#{store.main.entity.name}
後來在某環境下,不用seam,用Spring了,發現如下的代碼會有問題:
@Component("auth.main")//Spring的Annotation
public class MainAction{........}
在頁面上用#{auth.main.xx}這樣的表達式的時候,會出現找不到對象的錯誤。跟代碼發現Spring提供的SpringBeanFacesELResolver裡面解析的時候,先解析"auth",找不到,于是後面就解析不下去了。
問題的關鍵點在于這個EL解析器。Seam的ELResolver能夠正确解析帶命名空間的元件,而Spring的這個不行。
于是,擴充之。
首先第一步是要讓系統知道有哪些命名空間,這裡用了Spring的一個接口,叫做BeanFactoryPostProcesser,看名字應該能看的出來,和我們常用的BeanPostProcess道理一樣,隻不過實作了BeanFactoryPostProcesser接口的元件會在整個beanFactory初始化之前和之後調用。
看代碼:
這樣,在系統啟動的時候分析所有的bean的名字,把命名空間記錄下來。
然後,建立一個ELResolver,讓他能夠解析命名空間:
在JSF的配置檔案中啟用這個ELResolver:
這樣,就可以在頁面上用表達式引用帶命名空間的元件了。