那些隐藏的"钩子"

最近在玩JSF技术,当我部署一个最简单的JSF应用"guessNumber"的时候,在web.xml上面配置了如下的Servlet:

 

 <servlet>
    <display-name>FacesServlet</display-name>
    <servlet-name>FacesServlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>FacesServlet</servlet-name>
    <url-pattern>/guess/*</url-pattern>
  </servlet-mapping>

 

然后再无其他配置,例子竟然可以正常运行。顿时有了疑惑,怎么可能?什么时候读取的faces-config.xml? 什么时候初

始化的?下载jsf-api.jar和jsf-impl.jar的原代码,解压到src目录下,再运行一次,果然不行了,出来一个错误:

 

java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory

 

为什么?我把jsf-impl.jar中的META-INF目录下所有东西复制到我的META-INF下,再次尝试,还是不行。到网络上查到一个

解决方案,把如下的内容复制到web.xml即可:

 

<listener>
      <listener-class>com.sun.faces.config.ConfigureListener</listener-class >
   </listener> 

 

照着做,果然可以。但为什么在刚开始的例子中不需要这个配置呢?难道这个listener会自动被探测到,并进行注册吗?

我在jsf源代码中搜索ConfigureListener,才找到了答案。原来这个listener放在/META-INF/jsf_core.tld, 而根据"JavaServer Pages Specification 1.2"的规定,容器是可以自动探测到这个listener并自动注册的,下面是对它的描述:

 

    A tag library may include classes that are event listeners (see the Servlet 2.3
specification). The listeners classes are listed in the tag library descriptor and the
JSP container automatically instantiates them and registers them.

 

至于为什么你把源代码解压到src目录下就不行,原因是这种情况下,所有的tld文件应该放到WEB-INF目录下,下面是对它

的描述:

 

 When deployed inside a JAR file, the tag library descriptor files must be in the META-INF directory, or a
subdirectory of it. When deployed directly into a web application, the tag library descriptor files must always

be in the WEB-INF directory, or some subdirectory of it.

所以当以jsf-impl.jar形式存在,并放到WEB-INF/lib目录下,listener会自动被注册,当你解压成源代码后,你需要把所有的

tld文件移动到WEB-INF目录下。

 

总结成一句话,Java 平台里有大量这样的"钩子"或者"技巧",这为我们的学习增加了难度,我们需要熟悉很多的"背景知识",

这些"背景知识"就存在于各种"Specification"里面。

 

发布了34 篇原创文章 · 获赞 1 · 访问量 14万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览