Grails框架学习使用经验笔记.docx
- 文档编号:30392765
- 上传时间:2023-08-14
- 格式:DOCX
- 页数:38
- 大小:35.79KB
Grails框架学习使用经验笔记.docx
《Grails框架学习使用经验笔记.docx》由会员分享,可在线阅读,更多相关《Grails框架学习使用经验笔记.docx(38页珍藏版)》请在冰豆网上搜索。
Grails框架学习使用经验笔记
作者:
杨港
更新时间:
2011年9月5日10:
21:
35
1、在gsp页面里写注释,如果注释是中文的话,有时会出现gsp编译错误,可能跟中文字节有关系,解决办法:
在中文注释后多加一个空格
2、grails如果要连接数据库,那grails开头的jar必须放在项目WEB-INF/lib里,其他jar可以放在web服务器的共享lib里
3、grails中的gorm在操作数据库是出错,但没有任何日志记录
4、grails服务类的文件名与类的名称必需一致,不然虽然编译通过,但grails内部封装时无法正确识别
5、grails工件的类名称,第一个字母必需大写
6、grails同类工件的类名称不能重名,即使包名称不一样,类名称相同,这种情况也是不行,在grails内部会解析出现问题
7、服务类经验:
1)、grails服务类的名称,必须以Service结尾,不然在grails里无法正确识别。
2)、服务类运行时是单件模式。
3)、服务类默认是开启事务(数据库事务),如果没有用到数据库事务最好关闭事务,否则数据库连接可能占用过多,造成连接池里连接不够用。
statictransactional=false//禁用事务
8、配置使用经验:
1)、把数据库配置、日志配置都放在外面,运行时载入,这样工程部署完还可以修改配置。
实现方法如下:
修改Config.groovy
grails.config.locations=["classpath:
config/spy.properties"
"classpath:
config/Log4jConfig.groovy"
"classpath:
config/SystemConfig.groovy"
"classpath:
config/DataSource.groovy"
"classpath:
projectconfig/encode.properties"
]
//spy.properties配置必须放在Log4jConfig.groovy之前,否则Log4jConfig.groovy的配置将被spy.properties里的日志配置覆盖
2)、动态加载配置,在控制器里加入以下代码:
defwebBaseDir=ServletContextHolder.servletContext.getRealPath('/')
defclassdir=ApplicationHolder.application.isWarDeployed()?
FilenameUtils.concat(webBaseDir,'WEB-INF/classes'):
FilenameUtils.concat(webBaseDir,'../target/classes');
defindex={forward(action:
"reloadconfig")}
defreloadconfig={
//重新载入配置成功
defconfig=grailsApplication.config
defreload={
deflocations=config.grails.config.locations
locations.each{
if(it.startsWith('classpath:
')){
it=FilenameUtils.concat(classdir,it['classpath:
'.length()..-1])
it='file:
'+it
}
if(FilenameUtils.isExtension(it,'properties')){//properties文件
it=it.replace('file:
','file:
///')
defpro=newProperties()
defproFile=newFile(it)
if(proFile.exists()){
proFile.withInputStream{pro.loadit}
config.merge(newConfigSlurper().parse(pro))
}
}else{//groovy文件
config.merge(newConfigSlurper().parse(newURL(it)))
}
}
render"重新载入配置成功!
${newDate()}"
}
defauth=config.control.auth
if(auth){//是否需要验证
if(auth==params.auth){//验证成功
reload()
}else{//验证失败
render'你无权做此操作!
'
}
}else{
reload()
}
}
9、使用_Events.groovy把相关的配置在编译时就复制到指定的位置
eventCompileStart={
ant.copy(todir:
"$classesDir/config",overwrite:
true){fileset(dir:
"config")}
ant.copy(todir:
"$classesDir/projectconfig",overwrite:
true){fileset(dir:
"projectconfig")}
}
10、修改BuildConfig.groovy,把相关的配置在打包war时就复制到指定的位置
grails.war.resources={stagingDir,args->
copy(todir:
"${stagingDir}/WEB-INF/classes/config/",overwrite:
true){fileset(dir:
"config")}
copy(todir:
"${stagingDir}/WEB-INF/classes/projectconfig/",overwrite:
true){fileset(dir:
"projectconfig")}
}
11、当域类很多时,每次启动更新数据库结构时会非常慢,可能把DataSource文件里的dbCreate="update"//oneof'create','create-drop','update',
改成dbCreate="none",启动时不对数据库做任何操作,当需要更新数据库结构时再修改dbCreate="update"
12、如果需要gsp页面在运行时,修改直接生效,需要,在Config.groovy里加入grails.gsp.enable.reload=true
13、map操作中,map<<["$var",value]失败,需要用map<<[(var),value]或map.put(var,value)来代替:
defvar='mykey'
defmap=[:
]
map<<["$var",value]//可以执行,但map.mykey无法取值;所以此方法不行
map<<[(var),value]//OK建议的方式
map.put(var,value)//OK
14、layout应用与搜索顺序:
1)、gsp模板文件里指定的layout比如:
2)、在控制器里指定的layout比如:
staticlayout='main'
3)、layouts/{ControlerName}/{ActionName}.gsp
4)、layouts/{ControlerName}.gsp
5)、layouts/application.gsp
15、服务类不要太多,比较耗内存,Grails启动时,初始化也慢
16、在Grails应用里,根据类名称(包含包)获取类型:
Class.forName(params.servicename,true,this.getClass().getClassLoader())
17、根据类型获取Spring容器里的实例:
grailsApplication.mainContext.getBean(type)
获取所有已经定义的Bean的名称数组:
grailsApplication.mainContext.beanDefinitionNames
Grails内置的bean:
annotationHandlerAdapter,annotationHandlerMapping,classLoader,controllerHandlerMappings,controllerToScaffoldedDomainClassMap,
convertersConfigurationInitializer,customEditors,dataSource,dataSourceUnproxied,dialectDetector,entityInterceptor,errorsJsonMarshallerRegisterer,
errorsXmlMarshallerRegisterer,eventTriggeringInterceptor,exceptionHandler,filterInterceptor,flushingRedirectEventListener,
grailsApplicationPostProcessor,grailsUrlMappingsHolder,grailsUrlMappingsHolderBean,groovyPageResourceLoader,groovyPagesTemplateEngine,
groovyPagesUriService,gspTagLibraryLookup,hibernateEventListeners,hibernateProperties,jsonErrorsMarshaller,jsonParsingParameterCreationListener,
jspTagLibraryResolver,jspViewResolver,lobHandlerDetector,localeChangeInterceptor,localeResolver,mainSimpleController,messageSource,
multipartResolver,nativeJdbcExtractor,openSessionInViewInterceptor,org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib,
org.codehaus.groovy.grails.plugins.web.taglib.CountryTagLib,org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib,
org.codehaus.groovy.grails.plugins.web.taglib.FormatTagLib,org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib,
org.codehaus.groovy.grails.plugins.web.taglib.PluginTagLib,org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib,
org.codehaus.groovy.grails.plugins.web.taglib.SitemeshTagLib,org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib,
org.codehaus.groovy.grails.web.filters.JavascriptLibraryFilters,org.codehaus.groovy.grails.web.filters.JavascriptLibraryFiltersClass,
org.springframework.aop.config.internalAutoProxyCreator,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,
org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,
org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,
org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.config.internalTransactionAdvisor,
org.springframework.transaction.interceptor.TransactionInterceptor#0,persistenceInterceptor,pluginManagerPostProcessor,proxyHandler,
scaffoldedActionMap,scaffoldingTemplateGenerator,sessionFactory,shutdownHook,simpleControllerHandlerAdapter,transactionManager,
transactionManagerPostProcessor,urlMappingsTargetSource,viewNameTranslator,xmlErrorsMarshaller,xmlParsingParameterCreationListener
18、获取所有的服务类:
grailsApplication.getArtefacts('Service')
19、在Groovy源包里的类,如果设计成需要被继承的,那边不能放在默认包下,必须有包名称
20、在Groovy源包里的类,也可以调用域类的方法
21、动态调用类里的静态方法(即类可以用动态传参数):
defclassName="GroovyClass1"
deftype=Class.forName("info.$className",true,this.class.classLoader)
type.staticMethod('test')
22、因Groovy&Grails是增量编译的,有时侯会出现:
现有的代码与已经编译的类不同步(当认为代码没有问题,而就是出错时,很有可能是这种情况),需要先清理,再编译或运行。
23、域类的hasMany=[键:
域类型],其中“键”字符串不能太长,否则生成外键名称时,长度可能超过数据库里外键名称允许的长度
24、web服务器的全局lib,与项目的WEB-INF/lib里不能同时存在slf4j-log4j12*.jar包
25、grails由于域类、服务类多、加载的类多等关系,比较占perm内存,经常会内存溢出,需要修改jvm的perm内存配置。
建议直接用OracleJRockit代替OracleJDK、JRE,直接解决问题无需下面设置,并提高性能。
在tomcat操作如下:
需要在bin/catalina.sh(catalina.batwindows平台)调整一下jvm的内存设置,即在注释后面加上下面一句话,该配置内存量大小,根据实际来调整
catalina.bat:
setJAVA_OPTS=-Xms128m-Xmx1300m-XX:
PermSize=128m-XX:
MaxPermSize=500m
catalina.sh:
JAVA_OPTS='-Xms128m-Xmx1300m-XX:
PermSize=128m-XX:
MaxPermSize=500m'
==
26、放在默认包里的类,无法被继承,也无法在控制器里调用,所以类都要放在包里
27、升级Grails版本时,可能出现一些插件升级不了,删除grails的项目缓存就可以,一般在用户目录的.grails/projects
28、当使用一些插件时,如auto-test,jms等做造成在开发环境(grailsrun-app)运行时,会无故自动编译,可以禁止自动编译
grails-Ddisable.auto.recompile=truerun-app
29、如果想让grails生成的war包,部署在glassfish里,把BuildConfig.groovy里加入以下语句
grails.project.war.osgi.headers=false
30、用GORM批量(大量)维护数据时,性能相对与grovy.sql.Sql,jdbc等慢很多。
如果是主子表的话,用域类.addXXX(),GORM性能会急剧下降(不执行.save,)。
建议用grovy.sql.Sql,jdbc,直接数据库存储过程等高效方法。
31、在用File.setText('文件路径','utf-8'),保存成utf-8格式,如果文件内容里没有,中文等字符的,他还会被保存成本地编码,非utf-8编码
32、Grails的JMS插件经验:
1)、在Grails里使用jms插件时,在DataSource.groovy里必须配置数据源,否则会出下面错误:
2011-03-1620:
38:
50,571[MainThread]ERRORcontext.GrailsContextLoader-Errorexecutingbootstraps:
Errorcreatingbeanwithname'handleJmsListenerContainer':
Cannotresolvereferencetobean'handleJmsListenerAdapter'whilesettingbeanproperty'messageListener';nestedexceptionisorg.springframework.beans.factory.BeanCreationException:
Errorcreatingbeanwithname'handleJmsListenerAdapter':
Cannotresolvereferencetobean'persistenceInterceptor'whilesettingbeanproperty'persistenceInterceptor';nestedexceptionisorg.springframework.beans.factory.NoSuchBeanDefinitionException:
Nobeannamed'persistenceInterceptor'isdefined
2)、可以使用广播topic:
sendJMSMessage(topic:
"topic.test",'hello')
3)、在服务类与消息队列对接时,具备链接可靠性(即当Activemq停止,再启动,服务类会自动与消息队列对接),
不管Activemq在本机,还是在远程都具备可靠性。
如果使用了spring的jms连接池(SingleConnectionFactory),那就不具备可靠性(即运行过程中,Activemq挂了再恢复,Grails不会重新连接)。
4)、在服务类里设置staticlistenerCount=n,无效,不能达到多线程倾听的效果。
需要在配置文件里如下设置才有效果:
jms{
containers{
info{
meta{
parentBean='standardJmsListenerContainer'
}
sessionTransacted=true
concurrentConsumers=5//此句是关键,并发客户端数
}
}
adapters{
info{
meta{
parentBean='standardJmsListenerAdapter'
}
messageConverter=null//donomessageconversion
}
}
}
5)、.net用NMS向activemq发带属性的消息,在Grails里用JMS可以读出属性,如果再写入别的属性转发给别的队列,那么这些在Grails里写入的属性,无法读出。
如果.net里NMS发的消息不带属性,那么在Grails再写入别的属性,在别的队列里是可以读出这些属性的。
6)、相关的Beans:
jmsConnectionFactorystandardJmsListenerContainerjmsServiceinfoJmsListenerContainernew1JmsListenerAdapter
standardJmsMessageConverterinfoJmsListenerAdapternew1JmsListenerContainerstandardJmsTemplatestandardJmsListenerAdapter
grails.plugin.jms.JmsServiceServiceClass
注:
new1是服务类,info是在配置文件里配置的Container名称与Adapter名称
7)、jms插件底层调用SpringJMS,所以有时可以去SpringJMS的查看api,同时看看插件的在线向导与api。
8)、在调用sendJMSMessage方法,传发送内容参数时,如果是要发送文本消息(简单字符串),需要普通的String类型,不要用GString。
即用单引,不要用双引。
或把GString类型即“”后再.toString()变成String类型。
否则sendJMSMessage识别不了类型,被封装成ObjectMessage,而非TextMessage。
9)、activemq自带的fileserv
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Grails 框架 学习 使用 经验 笔记