Dwr里location参数小议

本文探讨了DWR与Spring框架结合使用时遇到的问题,并提出了解决方案。针对location参数导致的Hbm文件重复加载问题,作者提供了一种优化方法,通过自定义SpringLocationUtil类改进bean工厂的加载方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring+hibernate+dwr(1.14),location参数导致重复装载Hbm文件探讨。

近来,项目用到了dwr做ajax的应用。有点不爽的是,

1.使用了多个Bean文件,在Web.xml里定义顺序为application1.xml,applicaiton2.xml,applicaiton3.xml,

导致Spring在装载这些bean文件定义时,当前上下文里只会有一个bean定义文件,application1.xml.

其余的bean文件定义是放在ParentContext下。

2.通过WebContext取BeanFactory,只能是取第一个bean文件定义的工厂;

其他bean文件的bean只能是通过xmlpath的方式获取。

3.spring+dwr结合时,需在dwr.xml里定义creator的value是spring。由于dwr默认使用的spring

上下文工厂,当dwr文件里有其他bean文件定义的bean对象时,将会导致这些非第一个bean文件如:

(applicaiton2.xml,applicaiton3.xml)定义的bean对象在Dwr里不起作用。

4.dwr官方的方法是在dwr.xml文件里加入类似

的参数定义,如果大部分的bean对象是在第一个bean文件里定义的,处理还算可以。

如果有10多个bean对象不是在第一个bean文件里,加入一堆的location参数,每个bean就得装载一次

,在很多时候将会导致启动时发生OutofMemery的异常。

5.此时的方法有二,一是调整启动的容器内存参数,把内存调大。二,更改dwr的location参数装载方式。

6,最理想的方式,从parentContext里取得beanFactory;其次,在装载的时候就把读入bean定义

文件,在内存存储这些beanfactory对象,以备当使用了location参数时使用。

这样就可以一点程度上避免重复装载着启动时消耗过多的内存,加快容器部署速度。


以下是我更新DWR的location参数的代码

在uk.ltd.getahead.dwr.util包里新增一个类SpringLocationUtil

[code="java"]/*

* Copyright 2009 Jandytom

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*

* ClassDescription

* This class help people who want to use Spring bean file location param

* aware cycle build the bean defined xml file.

*/

package uk.ltd.getahead.dwr.util;


import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;


import org.dom4j.Attribute;

import org.dom4j.Document;

import org.dom4j.DocumentException;

import org.dom4j.Element;

import org.dom4j.ProcessingInstruction;

import org.dom4j.VisitorSupport;

import org.dom4j.io.SAXReader;

import org.springframework.beans.factory.BeanFactory;

import org.springframework.context.support.ClassPathXmlApplicationContext;


public class SpringLocationUtil {


private static SpringLocationUtil locationUtil = null;

private InputStream in;

private Map beanFactoryMap;

private Map beanFileMap;





private SpringLocationUtil(){

this.setBeanFileMap(new HashMap());

this.setBeanFactoryMap(new HashMap());

}



public synchronized static SpringLocationUtil getInstance(){



if(locationUtil==null){

locationUtil = new SpringLocationUtil();

}

return locationUtil;



}



class MyVistor extends VisitorSupport {

public void visit(Attribute node) {

log.debug("Attibute:---" + node.getName() + "="+ node.getValue());

}

public void visit(Element node) {

if (node.isTextOnly()) {

String nodeName = node.getName().trim();

if(nodeName.equals("param")){

String atrNameValue = node.attributeValue("name");

if(atrNameValue!=null&&atrNameValue.startsWith("location")){

String beaFileName = node.attributeValue("value");

if(beaFileName!=null){

beanFileMap.put(atrNameValue, beaFileName);

}

}

}

log.debug("Element:---" + node.getName() + "=" + node.getText());

}else{

log.debug("--------" + node.getName() + "-------");

}

}





public void visit(ProcessingInstruction node) {

log.debug("PI:"+node.getTarget()+" "+node.getText());

}

}

public void InitBeanFactoryMap(InputStream in){

SAXReader reader = new SAXReader();

try {

Document doc = reader.read(in);

doc.accept(new MyVistor());

Map beanMap = new HashMap();

if(beanFileMap!=null&&beanFileMap.size()>0){

for (Iterator it = beanFileMap.entrySet().iterator(); it.hasNext();)

{

Map.Entry entry = (Entry) it.next();

String key = (String) entry.getKey();

Object value = entry.getValue();

BeanFactory factory = new ClassPathXmlApplicationContext(String.valueOf(value));

beanMap.put(value, factory);

}

this.setBeanFactoryMap(beanMap);

}else{

log.info("location param not found .");

}



} catch (DocumentException e) {

e.printStackTrace();

}finally{

if(in!=null){

try {

in.close();

} catch (IOException e) {

e.printStackTrace();

log.error("Close InputStream Error:"+e.getMessage());

}

}

}

}



public static void main(String args[]){

java.io.File file = new java.io.File("D:\\work\\eclipse\\workspaceAll\\Test\\WebRoot\\WEB-INF\\dwr.xml");

try {

InputStream in = new java.io.FileInputStream(file);

SpringLocationUtil.getInstance().InitBeanFactoryMap(in);

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}





}





public InputStream getIn() {

return in;

}


public void setIn(InputStream in) {

this.in = in;

}


public Map getBeanFactoryMap() {

return beanFactoryMap;

}


public void setBeanFactoryMap(Map beanFactoryMap) {

this.beanFactoryMap = beanFactoryMap;

}


public Map getBeanFileMap() {

return beanFileMap;

}


public void setBeanFileMap(Map beanFileMap) {

this.beanFileMap = beanFileMap;

}

/**

* The log stream

*/

private static final Logger log = Logger.getLogger(SpringLocationUtil.class);

}

[/code]


然后,更改AbstractDWRServlet,更新后的Servlet init()方法如下,红色部分为修改内容

[code="java"] public void init(ServletConfig config) throws ServletException

{

super.init(config);


try

{

ServletLoggingOutput.setExecutionContext(this);


// How much logging do we do?

String logLevel = config.getInitParameter(INIT_LOGLEVEL);

if (logLevel != null)

{

ServletLoggingOutput.setLevel(logLevel);

}


// call the abstract method to obtain the container

container = getContainer(config);


// Now we have set the implementations we can set the WebContext up

builder = (WebContextBuilder) container.getBean(WebContextBuilder.class.getName());

WebContextFactory.setWebContextBuilder(builder);


// And we lace it with the context so far to help init go smoothly

builder.set(null, null, getServletConfig(), getServletContext(), container);


// Load the system config file

Configuration configuration = (Configuration) container.getBean(Configuration.class.getName());

InputStream in = getClass().getResourceAsStream(FILE_DWR_XML);

log.info("retrieved system configuration file: " + in); //$NON-NLS-1$

InputStream inPlug = config.getServletContext().getResourceAsStream(DEFAULT_DWR_XML);

try

{ SpringLocationUtil.getInstance().InitBeanFactoryMap(inPlug);

  configuration.addConfig(in);

}

catch (Exception ex)

{

log.fatal("Failed to load system config file from dwr.jar", ex); //$NON-NLS-1$

throw new ServletException(Messages.getString("DWRServlet.SystemConfigError"), ex); //$NON-NLS-1$

}


// call the abstract method to perform additional configuration

configure(config, configuration);


// Finally the processor that handles doGet and doPost

processor = (Processor) container.getBean(Processor.class.getName());

}

catch (ServletException ex)

{

throw ex;

}

catch (Exception ex)

{

log.fatal("init failed", ex); //$NON-NLS-1$

throw new ServletException(ex);

}

finally

{

if (builder != null)

{

builder.unset();

}


ServletLoggingOutput.unsetExecutionContext();

}

}[/code]


更新uk.ltd.getahead.dwr.create.SpringCreator的getBeanFactory()方法

[code="java"] /**

* @return A found BeanFactory configuration

*/

private BeanFactory getBeanFactory()

{

// If someone has set a resource name then we need to load that.

if (configLocation != null && configLocation.length > 0)

{

log.info("Spring BeanFactory via ClassPathXmlApplicationContext using " + configLocation.length + "configLocations."); //$NON-NLS-1$ //$NON-NLS-2$

return (BeanFactory) SpringLocationUtil.getInstance().getBeanFactoryMap().get(configLocation[0]);

//return new ClassPathXmlApplicationContext(configLocation);

 }


ServletContext srvCtx = WebContextFactory.get().getServletContext();

HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();


if (request != null)

{

return RequestContextUtils.getWebApplicationContext(request, srvCtx);

}

else

{

return WebApplicationContextUtils.getWebApplicationContext(srvCtx);

}

}[/code]


编译后更新相关的Class即可。这个对使用location参数多的应用效果比较明显。

注:改动后的jar包只在Tomcat5.0.28下做过测试,其他容器未做测试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值