换种方式整合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!");}}}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;}}