在自定义标签子类获取Spring中注册的bean

自定义标签子类是:
javax.servlet.jsp.tagext.SimpleTagSupport
javax.servlet.jsp.tagext.TagSupport

... ...
的子类.当然在这些子类中访问Spring的bean也代表着与Spring的框架紧紧联系在一起.因为在这些类中无法使用Spring IoC.只能用Spring的:WebApplicationContextUtils.getWebApplicationContext(sc)方法去查找想要的bean.肯定有人会说这样是不好的!不推荐的.从另一个方面来说WebApplicationContextUtils.getWebApplicationContext方法肯定有存在的必要.下面是一个场景:

公共资源
例如社保系统中的险种(养老,医疗,工伤,...).在险种申报,收费,参保中都要用到他.哪就要考虑复用.保存这些资源有很多方式:xml,properties,数据库.

xml:
可以用单体类.

properties:
可以用单体类,工具类

数据库:
对于企业级应用(用浏览器作表示层).就要考虑在多个jsp页面中复用.jsp中复用我首选 的就是自定义标签.这样可以消灭jsp中的java代码. 这里就存在两种情况:
1.用struts获取spring管理的bean读取险种.把一个列表放到request中,在jsp中把险种列表作为参数传给自定义标签.
一开始我就用此方法.可以用险种列表呈现不同的html tag:可以用select,checkbox. 但后来发现几乎都是用的同一种html tag:select.随即也发现了一个问题:比如一个jsp页面.它只用到了险种列表.但我写一个action.所以能不能自定义标签中获取险种列表呢.?

2.在自定义标签中获取spring管理的bean读取险种
有了1的经验.马上声明一个类继承:SimpleTagSupport.在doTag()方法中用WebApplicationContextUtils.getWebApplicationContext方法获取spring管理bean,调用bean的方法获取险种列表.马上抛出了空指针异常 (NullPointerException).于是有了此贴:
http://topic.csdn.net/u/20090902/16/b0400979-11fe-4744-bd84-2e49fb27facd.html

有人说用:WebApplicationContextUtils.getRequiredWebApplicationContext() 方法.虽然spring的参考手册也推荐用此方法.但这不是这里的关键所 在.这两个方法在WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 这个键值不对应任何对象的时候getWebApplicationContext方法返回null,getRequiredWebApplicationContext() 方法会抛出:IllegalStateException异常

老紫竹说的对.按照他的提示我看了看spring的参考手册在15.2:通用配置一节中有一段话:
all that one need do is to declare a ContextLoaderListener  in the standard J2EE servlet web.xml file of one's web application, and add a contextConfigLocation <context-param/> section (in the same file) that defines which set of Spring XML cpnfiguration files to load.
Find below the <listener/> configuration:

Find below the <context-param/> configuration:
 

我就不明白了.要在web.xml中装载一个listener.但在struts.xml中我有装载applicationContext.xml呀:


来看看tomcat的启动消息吧:
A.以下是web.xml中没配置org.springframework.web.context.ContextLoaderListener的顺序:
...
信息: Starting Servlet Engine: Apache Tomcat/6.0.18
2009-9-8 14:15:57 org.apache.catalina.core.ApplicationContext log
信息: Set web app root system property: 'webapp.root' = [D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/proangle/]

2009-9-8 14:15:57 org.apache.catalina.core.ApplicationContext log
信息: Initializing Log4J from [D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/proangle/WEB-INF/log4j.properties]

2009-9-8 14:15:58 org.apache.catalina.core.ApplicationContext log
信息: Initializing WebApplicationContext for Struts ActionServlet 'action', module ''

2009-9-8 14:16:02 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on http-8080
...
信息: Server startup in 7744 ms


B.以下是web.xml中配置org.springframework.web.context.ContextLoaderListener的顺序:
...
信息: Starting Servlet Engine: Apache Tomcat/6.0.18
2009-9-8 10:16:20 org.apache.catalina.core.ApplicationContext log         
信息: Set web app root system property: 'webapp.root' = [D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/proangle/]        

2009-9-8 10:16:20 org.apache.catalina.core.ApplicationContext log
信息: Initializing Log4J from [D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/proangle/WEB-INF/log4j.properties]        
//----------------------------------------------------------------------
2009-9-8 10:16:21 org.apache.catalina.core.ApplicationContext log
信息: Loading Spring root WebApplicationContext
//----------------------------------------------------------------------
2009-9-8 10:16:26 org.apache.catalina.core.ApplicationContext log
信息: Initializing WebApplicationContext for Struts ActionServlet 'action', module ''      
 
2009-9-8 10:16:26 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on http-8080
...
信息: Server startup in 9609 ms

从顺序可以看出在struts启动WebApplicationContext 要晚于web.xml中的listener.这个想想也能猜出来.struts毕竟是以servlet的形式注册到web.xml的.至于不在web.xml中配置ContextLoaderListener取不到spring的bean.只能这样推断.自定义标签无法共享struts装载的WebApplicationContext..

测试以上结果的环境:
Spring-Version: 2.0.2
struts 1.2.9
jdk 6
tomcat 6

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值