Jsf与Spring的整合原理
Jsf做为Web框架,Spring做为业务层框架,两者可以结合起来用。只要在faces-config.xml中做一个很简单的配置:
<faces-config>
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
...
</application>
</faces-config>
理解这个配置,就需要接触到Java平台中一个常用的概念:Resolver。它的意思是“解决者”。遇到一个陌生的东西,怎么
处理就需要找相应的Resolver。比如在一个视图文件jsp中,有这么一行:
<h:outputTextvalue="#{welcome.hello}"/>
其中welcome是注册在Spring中的一个组件,并没有注册成Jsf的managedbean。当解析到#{welcome.hello}时候,Jsf框架去
找注册的managedbean,当然它会找不到,系统在这个位置不会有任何显示。而当我们加上上面的el-resolver时,Jsf框架会
在Spring框架中找。
当然你也可以在managedbean配置中注入Spring管理的bean,例如:
<managed-property>
<property-name>welcome</property-name>
<property-class>guessNumber.Welcome</property-class>
<value>#{welcome}</value>
</managed-property>
Jsf框架读取这个配置文件,也会到Spring中找到名字为“welcome”的bean.
Jsf寻找的过程是一个职责链模式,它从一系列的Resolver中寻找需要的东西,一旦找到,即返回。这个链是有顺序的,这个
顺序在JsfSpec中有清晰的定义。比如有两个不同bean,一个注册在Sping中,另一个注册在Jsf中,你不小心给了相同的名字,
它会先去Sping中找,最终Spring中注册的bean起了作用。
打开SpringBeanFacesELResolver源代码,我们可以看到它最终继承了一个抽线类:ELResolver。这个类中的方法都有一个参数
ELContext,从ELContext中顺藤摸瓜得到servletContext,然后取出名字为
"org.springframework.web.context.WebApplicationContext.ROOT"
的变量,此变量即为Sping中的WebApplicationContext,有了这个,万事大吉,我们可以从中取出所有注册过的bean.
那么又是谁把这个变量放到
servletContext中了呢,当然是
"org.springframework.web.context.ContextLoaderListener"了。