读书人

换类方式整合Opencms和Spring+Hiberna

发布时间: 2012-10-25 10:58:57 作者: rapoo

换种方式整合Opencms和Spring+Hibernate
官方wiki上给出的解决方法是:http://www.opencms-wiki.org/Spring

上面的方案和我们自己写的Spring应用差不多,都是在web.xml加入listener,然后各个context.xml放入到web path下。不过这种做法对Opencms侵入性比较大,涉及到以后对Opencms升级或者在一个Opencms上进行多个应用开发的时候都会有冲突麻烦。Opencms里面强调module概念我们应该好好利用下,我的想法是这样:

做一个Spring支持的模块,该模块为其他模块提供Spring IOC的支持,以往和Spring MVC绑定在一起的Spring应用,都是用Spring自带的listenner把beanFactory绑到ServletContext上。我们可以让这个自定义的模块为Opencms提供全局的工厂,和Spring MVC完全脱离了关系,当然也可以使用spring MVC或者struts,这个不在我讨论范围内。这个模块可以在启动时候扫描全局模块中的context.xml(注意:这个文件放在各自的模块的vfs中,而不是Opencms中的物理路径下)并加载!有了这样一个模块的话,开发人员开发其他模块的时候只需要在相应的自定义模块中指定context.xml文件内容和bean的src就可以了。

下面给出一个简单实现:

新建一个名为com.sino.opencms.springframework的Opencms module,首先建立一个module的启动类,所有处理都在此类中。

package com.sino.opencms.springframework;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Set;import org.apache.commons.logging.Log;import org.opencms.configuration.CmsConfigurationManager;import org.opencms.file.CmsFile;import org.opencms.file.CmsObject;import org.opencms.file.CmsResourceFilter;import org.opencms.main.CmsLog;import org.opencms.main.OpenCms;import org.opencms.module.A_CmsModuleAction;import org.opencms.module.CmsModule;import org.springframework.context.ApplicationContext;import org.springframework.core.io.ByteArrayResource;import org.springframework.core.io.Resource;public class ContextLoaderAction extends A_CmsModuleAction {public static ApplicationContext staticFactory;private static final Log LOG = CmsLog.getLog(ContextLoaderAction.class);@SuppressWarnings("unchecked")public void initialize(CmsObject adminCms,CmsConfigurationManager configurationManager, CmsModule module) {if(LOG.isInfoEnabled())LOG.info("contextLoaderAction staring!");Set<String> names = OpenCms.getModuleManager().getModuleNames();/** * openCms中xml资源type为1,txt为2 */List<Resource> resources = new ArrayList<Resource>();for (String name : names) {try {//获得Opencms vfs中各模块的config目录下面的xml文件List files = adminCms.getFilesInFolder("/system/modules/"+name+"/config",CmsResourceFilter.requireType(1));Iterator filesIt = files.iterator();while(filesIt.hasNext()){String path = ((CmsFile) filesIt.next()).getRootPath();CmsFile f = adminCms.readFile(path);Resource resource = new ByteArrayResource(f.getContents());resources.add(resource);if(LOG.isInfoEnabled())LOG.info("find resource in "+path);}} catch (Exception e) {}}if(resources.size() > 0){Resource[] resourceArrays = new Resource[resources.size()];ApplicationContext factory = new OpenCmsSpringApplicationContext(resources.toArray(resourceArrays));this.staticFactory = factory;}else{LOG.warn("Not SpringApplicationContext loaded in system!");}}}


由于Opencms模块里的资源都是byte类型,所以spring自带的那些ResourceLoader不支持现有情况,所以我们还要自定义一个XmlApplicationContext加载器来加载存在Opencms中的xml子节流。实现如下:

package com.sino.opencms.springframework;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.support.AbstractXmlApplicationContext;import org.springframework.core.io.Resource;/** * @project: com.sino.opencms.springframework * @description: 以OpenCms中的资源建立的Spring ApplicationContext * @author: kongji * @create_time: Oct 29, 2008 * @modify_time: Oct 29, 2008 */public class OpenCmsSpringApplicationContext extendsAbstractXmlApplicationContext {private Resource[] configResources;public OpenCmsSpringApplicationContext(Resource[] configResources)throws BeansException {this(configResources,true,null);}public OpenCmsSpringApplicationContext(Resource[] configResources,boolean refresh, ApplicationContext parent) throws BeansException {super(parent);this.configResources = configResources;if (refresh) {refresh();}}protected Resource[] getConfigResources() {return this.configResources;}}


然后在模块lib中放入spring hibernate需要的lib包

其他的模块只要建立以后在各自模块目录下建立一个config目录,然后放入自己的spring上下文xml文件就可以了。

在Opencms的jsp页面或taglib中可以这样使用服务:
<%
ApplicationContext ac = ContextLoaderAction.staticFactory;
xxx service = (xxx) ac.getBean("xxxService");
%>

目前项目开发的模式:在eclispe里面用编写各个模块(使用opencms.module.developer插件),然后子模块项目都依赖于此模块,这样互相引用的时候不会报错,上传到Opencms服务器上以后所有资源就都在一个class path下了。

由于opencms.module.developer插件本身不支持spring xml格式文件上传,上传的时候它会检查xml格式,它认为是Opencms的内容文件,肯定会报错不通过,这点很讨厌,附件里给一个修改以后的插件,允许上传spring的xml文件。

读书人网 >软件架构设计

热点推荐