Grails 在bootstrap中使用groovy元类模拟Shiro SecurityUtils
有关更多背景信息,请参阅 我试图在BootStrap.groovy中模拟Shiro SecurityUtils.getSubject()方法。我决定采用这种方法是因为最新Shiro版本中的主题生成器在当前版本的灵活插件(我正在使用)中不可用。我决定尝试使用SecurityUtils.metaClass,但我有一种感觉,我遗漏了一些关于元类如何工作的非常基本的东西。作为参考,以下是我的可跟踪类:Grails 在bootstrap中使用groovy元类模拟Shiro SecurityUtils,grails,groovy,metaprogramming,shiro,bootstrapping,Grails,Groovy,Metaprogramming,Shiro,Bootstrapping,有关更多背景信息,请参阅 我试图在BootStrap.groovy中模拟Shiro SecurityUtils.getSubject()方法。我决定采用这种方法是因为最新Shiro版本中的主题生成器在当前版本的灵活插件(我正在使用)中不可用。我决定尝试使用SecurityUtils.metaClass,但我有一种感觉,我遗漏了一些关于元类如何工作的非常基本的东西。作为参考,以下是我的可跟踪类: abstract class Trackable { User createdB
abstract class Trackable {
User createdBy
Date dateCreated
User lastUpdatedBy
Date lastUpdated
static constraints = {
lastUpdated(nullable:true)
lastUpdatedBy(nullable:true)
createdBy(nullable:true)
}
def beforeInsert = {
def subject
try {
subject = SecurityUtils.subject
} catch (Exception e) {
log.error "Error obtaining the subject. Message is [${e.message}]"
}
createdBy = (subject ? User.get( subject.principal ) :
User.findByUsername("admin"))
}
def beforeUpdate = {
def subject
try {
subject = SecurityUtils.subject
} catch (Exception e) {
log.error "Error obtaining the subject. Message is [${e.message}]"
}
lastUpdatedBy = (subject ? User.get( subject.principal ) :
User.findByUsername("admin"))
}
}
在我的BootStrap.groovy中,我有:
def suMetaClass = new ExpandoMetaClass(SecurityUtils)
suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
suMetaClass.initialize()
SecurityUtils.metaClass = suMetaClass
这就行了。。。某种程度上。如果我从BootStrap.groovy打印出主题,我会得到“罐头主题”。如果我尝试创建并保存Trackable子类的实例,我会得到:
我是否遗漏了元类如何工作的一些完整信息?我知道发生了什么。在我的引导过程中,我做了如下工作:
def init = { servletContext->
switch (Environment.current.name) {
case "local":
def suMetaClass = new ExpandoMetaClass(SecurityUtils)
suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
suMetaClass.initialize()
SecurityUtils.metaClass = suMetaClass
new TrackableSubClass().save()
//Create some other domain instances
SecurityUtils.metaClass = null
}
//Create a couple domain instances that aren't environment specific
}
我添加了一些调试语句,发现我看到的错误发生在init闭包的末尾。我在谷歌上搜索了一下,再次检查了如何刷新我的休眠会话。然后我做了以下更改:
def sessionFactory
def init = { servletContext->
switch (Environment.current.name) {
case "local":
def suMetaClass = new ExpandoMetaClass(SecurityUtils)
suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
suMetaClass.initialize()
SecurityUtils.metaClass = suMetaClass
new TrackableSubClass().save()
//Create some other domain instances
sessionFactory.currentSession.flush()
SecurityUtils.metaClass = null
}
//Create a couple domain instances that aren't environment specific
}
这似乎已经完全解决了这个问题,现在我应该能够从Trackable中删除繁琐的try/catch块了。:-) 我想知道这是否与Grails1.1.1在Groovy1.6.3上相关?
def sessionFactory
def init = { servletContext->
switch (Environment.current.name) {
case "local":
def suMetaClass = new ExpandoMetaClass(SecurityUtils)
suMetaClass.'static'.getSubject = {[getPrincipal:{2}, toString:{"Canned Subject"}] as Subject}
suMetaClass.initialize()
SecurityUtils.metaClass = suMetaClass
new TrackableSubClass().save()
//Create some other domain instances
sessionFactory.currentSession.flush()
SecurityUtils.metaClass = null
}
//Create a couple domain instances that aren't environment specific
}