我可以将服务注入Grails中的过滤器吗?

我可以将服务注入Grails中的过滤器吗?,grails,Grails,我有一个服务来获取和设置会话中的用户。如果有登录的用户,我想向每个视图传递一些用户信息,并认为过滤器是最好的方式,因此我不必在每个控制器/操作中重复这些信息。当我运行应用程序时,它会出现以下错误: Error creating bean with name 'userService': Scope 'session' is not active for the current thread 我的过滤器如下所示: class SecurityFilters { def userServi

我有一个服务来获取和设置会话中的用户。如果有登录的用户,我想向每个视图传递一些用户信息,并认为过滤器是最好的方式,因此我不必在每个控制器/操作中重复这些信息。当我运行应用程序时,它会出现以下错误:

Error creating bean with name 'userService': Scope 'session' is not active for the current thread
我的过滤器如下所示:

class SecurityFilters {
    def userService

    def filters = {
        setUser(controller:'*', action:'*') {
            before = {
                if (userService.isLoggedIn()) {
                    request.user = userService.getUser()
                } else {
                    request.user = null
                }
            }
        }
    }   
}

我知道我最终可以通过session.user访问该用户,但我希望能够调用userService.isLoggedIn(),我无法轻松地通过视图访问该用户。那么,有没有办法将服务注入到过滤器中,或者我应该创建一个taglib来包装userService.isLoggedIn()?

过滤器中的服务似乎存在一些问题。此错误可能会为您指明正确的方向:


您还可以尝试通过
ApplicationContext
获取对您的服务的引用。下面是一个示例:

问题似乎在于您的用户服务的作用域是会话,并且在尝试将服务注入筛选器时不一定存在会话

如果您的userService必须是会话作用域,那么您需要在spring配置中使用作用域代理。例如,在grails app/conf/spring/resources.groovy中:

import com.your.service.UserService
...
userServiceSession(UserService)
{ bean ->
    bean.scope = 'session'
}
userServiceSessionProxy(org.springframework.aop.scope.ScopedProxyFactoryBean)
{
    targetBeanName = 'userServiceSession'
    proxyTargetClass = true
}
然后在SecurityFilter中重命名注入的变量:

def userServiceSessionProxy
(显然,在类中其他地方使用它的地方重命名)

这应该做的是在注入时注入代理,但只在执行筛选器时(当存在会话时)转到实际服务


注意:不确定这样做是否仍然会让其他将有会话的地方(例如控制器)仍然将服务引用为“userService”,如果不是,您可能可以在resources.groovy中将userServiceSession重命名为userService(并相应地更新targetBeanName)

这听起来是一个有效的解决方案,但我选择了切换到taglib。看起来更简单,答案是不行。我添加了一条明显被删除的评论,说我不能,并提供了一种不同的方法。
import org.codehaus.groovy.grails.web.context.ServletContextHolder
import org.springframework.context.ApplicationContext
import org.springframework.web.context.support.WebApplicationContextUtils
class SecurityFilters {
    def userService

    def filters = {
        setUser(controller:'*', action:'*') {
            before = {
                def servletCtx = ServletContextHolder.getServletContext()
                ApplicationContext applicationContext = WebApplicationContextUtils.
                    getRequiredWebApplicationContext(servletCtx)
                userService =applicationContext.getBean('userService')
                if (userService.isLoggedIn()) {
                    request.user = userService.getUser()
                } else {
                    request.user = null
                }
            }
        }
    }   
}