重要更新
我能够得到你正在寻找的东西。逐步放下它:
要求-修改类
时,应刷新类以引用修改后的辅助类。Helper
service
设置
//src/groovy
class SampleHelper {
String name = 'Heisenberg'
def sayMyName(){
"$name"
}
}
//grails-app/service
import javax.annotation.PostConstruct
class SampleService {
String cachedName
@PostConstruct
def initIt(){
cachedName = new SampleHelper().sayMyName()
}
def serviceMethod() {
cachedName
}
}
//controller
class SampleController {
def sampleService
def index() {
render sampleService.serviceMethod()
}
}
问题陈述
当name
帮助类更新为Gus
时,该类会刷新,但服务类仍引用 的旧实例SampleHelper
。结果,名称仍然显示Heisenberg
。
解决方案
- 观看助手类。
- 刷新
onChange
助手类的服务类。
这可以通过在应用程序中使用Pluginator 插件来实现,该插件可以灵活地监视文件并执行某些onChange
事件。
- 安装插件。
- 在下面添加以下
ApplicationPlugin.groovy
内容grails-app/conf
。
作为
class ApplicationPlugin {
//Watch the helper class
def watchedResources = "file:./src/groovy/**/*.groovy"
//Re-Register the bean (service class) onChange of Helper Class
//This can be generalized more.
def onChange = { event ->
if (event.source) {
def beans = beans {
sampleService(SampleService) { bean ->
bean.autowire = true
}
}
if (event.ctx) {
event.ctx.registerBeanDefinition(
"sampleService",
beans.getBeanDefinition("sampleService"))
}
}
}
}
笔记
- 如果所有类和人工制品都遵循此过程,则可能会占用大量资源。
旧的和有效的答案
我无法在 Grails 2.2.0 中重现您的问题。以下是我的设置(如果我在任何地方错了,请纠正我):
//src/groovy
class MyHelper{
def sayMyName(){
"Heisenberg"
}
}
//service
import javax.annotation.PostConstruct
class MyService {
def myHelper
@PostConstruct
def initIt(){
myHelper = new MyHelper()
}
def serviceMethod() {
myHelper.sayMyName()
}
}
//controller (to test)
class MyController {
def myService
def index() {
render myService.serviceMethod()
}
}
脚步:
- 运行初始设置。(
run-app
)
- 点击控制器查看“海森堡”
- 修改
MyHelper.sayMyName()
以返回“Walter White”而不是“Heisenberg”
- 再次点击控制器并看到“Walter White”
观察:
- 我宁愿制作
MyHelper
一个bean并在服务类中使用(注入)它以供使用。
进入resources.groovy
如下:
beans = {
myHelper(com.example.MyHelper)
}
服务类变为:
class MyService {
def myHelper
def serviceMethod() {
myHelper.sayMyName()
}
}
- 现在,在服务类中引用字段
MyHelper
会产生问题,因为 bean 已经在容器中实例化了
关于奖金问题:
我无法在 Grails 2.2.0 中重现该问题
//domain
class MyDomain {
String name
}
//controller action
def add(){
def myDomain = new MyDomain(name: 'Testing').save(flush: true)
render myDomain.properties
}
- 更改域,添加
String email
- 保存域类。
- 修改要添加
email
的操作MyDomain
(显然将创建一个新行)。
- 保存控制器。
- 再次击中动作。
- 查看结果。