欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

GORM的独立启动(Standalone) grailsgormstandalonegroovyhibernate 

程序员文章站 2022-06-07 14:47:27
...

 

Gorm是Grails框架的orm(基于Hibernate)。Gorm用起来很方便,比直接用Hibernate方便。

很多用过Grails框架的开发者都有把Gorm独立拿出来使用的想法。比如有一些代码是在Grails环境里写的,但是想脱离web服务器使用。grails倒是可以命令行运行脚本,但是需要在grails应用的目录上运行,需要源代码,并且会有构建过程。

这个问题grails官方没有提供完整的方案。我通过查看grails的相关代码,解决了这个问题。贴出来和大家分享。

 

这个方案没有完全脱离grails,还是要使用grails的包,还是按grails的方式启动,只是过滤了不需要的资源(如Controller和Taglib)和插件。

 

共有以下文件(假设在~/standalone目录下):

 

wy-starter.conf
log4j.properties
xxx.groovy
bootstrap/
    Bootstrap.groovy
    RFGrailsPluginManagerFactoryBean.groovy
    RFGrailsApplicationFactoryBean.groovy
lib/
    spring-test-3.1.0.RELEASE.jar
    jansi-1.2.1.jar
    ant-1.8.2.jar
    jna-3.2.3.jar
    jline-1.0.jar
    servlet-api-2.4.jar
    gant_groovy1.8-1.9.6.jar
    commons-cli-1.2.jar
 

 


另外需要grails应用部署(War解压后的目录)路径。指定部署路径是为了方便,其实只需要WEB-INF下的grails.xml、plugins、classes、lib。其中classes和lib在wy-starter.conf里设置类路径。


wy-starter.conf是groovy的启动配置文件;xxx.groovy是要运行的脚本文件;假设war包解压目录为~/standalone/wy

wy-starter.conf内容如下:
load ~/standalone/wy/WEB-INF/classes
load ~/standalone/wy/WEB-INF/lib/*.jar
load ~/standalone/lib/*.jar
load ~/standalone/bootstrap/*.groovy
load ${tools.jar}
 
xxx.groovy内容如下:
import bootstrap.*

def wyBase=System.getenv('WY_WEB_APP_BASE')
def appCtx=Bootstrap.bootstrap(wyBase)

//使用GORM的业务代码...

 

bootstrap/Bootstrap.groovy是启动Gorm环境的类:

 

package bootstrap

import org.codehaus.groovy.grails.commons.*
import org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator
import org.codehaus.groovy.grails.plugins.GrailsPluginManagerFactoryBean
import org.codehaus.groovy.grails.core.io.*
import org.codehaus.groovy.grails.web.context.*
import grails.spring.WebBeanBuilder

import org.springframework.core.io.FileSystemResource
import org.springframework.mock.web.MockServletContext

class Bootstrap {

    static def bootstrap(appBase){
		
		if(appBase.endsWith('/') || appBase.endsWith('\\')){
			appBase=appBase[0..-2]
		}

        def beanDefinitions = new WebBeanBuilder().beans {
            grailsResourceLoader(GrailsResourceLoaderFactoryBean)
            grailsDescriptor(FileSystemResource,"$appBase/WEB-INF/grails.xml")
            grailsApplication(RFGrailsApplicationFactoryBean){
                grailsDescriptor = ref(grailsDescriptor)
                grailsResourceLoader = ref("grailsResourceLoader")
            }
            pluginManager(RFGrailsPluginManagerFactoryBean){
                grailsDescriptor = ref(grailsDescriptor)
                application = ref(grailsApplication)
            }
            grailsConfigurator(GrailsRuntimeConfigurator,grailsApplication){
                pluginManager = ref("pluginManager")
            }
        }

        def appCtx = beanDefinitions.createApplicationContext()

        //grailsApp = appCtx.grailsApplication
        def servletContext = new MockServletContext(appBase,new PluginPathAwareFileSystemResourceLoader())
        appCtx.servletContext=servletContext
        servletContext.setAttribute(ApplicationAttributes.APPLICATION_CONTEXT, appCtx)

        ExpandoMetaClass.enableGlobally()

        def webCtx = GrailsConfigUtils.configureWebApplicationContext(servletContext, appCtx)
        //GrailsConfigUtils.executeGrailsBootstraps(grailsApp, webCtx, servletContext)
		
        def persistenceInterceptor = webCtx.containsBean('persistenceInterceptor') ? webCtx.persistenceInterceptor : null
        persistenceInterceptor?.init()

        return webCtx
    }

}

 

 

bootstrap/RF*只是在grails的GrailsPluginManagerFactoryBean.groovy和GrailsApplicationFactoryBean.groovy的基础上增加了过滤的功能(前者过滤Controller和Taglib,后者过滤了除Hibernate外的插件)。直接用Grails的也是可以的,只不过多加载一些东西。代码就不必贴出来了。

 

数据库的连接配置和grails一样,如果配置在grails-app/conf/DataSource.groovy的话,已经编译到classes里去了。事实上,grails-app/conf里所以的配置都是可用的。


最后,要运行xxx.groovy,可以这样:

 

cd ~/standalone
export GROOVY_CONF=~/standalone/wy-starter.conf
export WY_WEB_APP_BASE=~/standalone/wy
groovy xxx.groovy

注意GROOVY_CONF变量静态定义的话(如放在~/.profile)会影响i此用户运行其他groovy脚本。以上命令以linux环境为例,如果你的环境是windows应该知道怎么做吧。

至此,大功告成。