grails源码分析---之Filters机制(1)

grails提供了两种对请求的拦截机制,一是在Controller中定义beforeInterceptor和afterInterceptor两个方法,分别在执行action之前和之后调用,具体实现代码是在SimpleGrailsController和SimpleGrailsControllerHelper中,不再赘述。
还有一个是Filter,即在grails-app/conf目录下定义以Filters结尾的groovy文件既可,提供了三个拦截方法before,after,afterView,分别对应Spring MVC的HandlerInterceptor接口的preHandle(在处理请求前调用),postHandle(在处理请求后生成View之前调用,提供了修改Model的机会),afterCompletion(在请求处理完毕生成View之后调用)。
看看源码即可发现其实grails的MVC即是在Spring MVC框架上包装一层而成的,所以看来暂时不可能把核心框架修改为struts的可能。
下面看看grails是如何把Filters结尾的groovy文件变成Spring的HandlerInterceptor。
DefaultGrailsPlugin加载所有的plugin,当然也包含FiltersGrailsPlugin
DefaultGrailsPlugin.groovy

//加载plugin,调用plugin的doWithApplicationContext方法
public void doWithRuntimeConfiguration(
RuntimeSpringConfiguration springConfig) {

if(this.pluginBean.isReadableProperty(DO_WITH_SPRING)) {
if(LOG.isDebugEnabled()) {
LOG.debug("Plugin " + this + " is participating in Spring configuration...");
}
//调用plugin的doWithSpring方法,加载plugin到spring的ApplicationContext,使用Spring DSL方式的BeanBuilder
Closure c = (Closure)this.plugin.getProperty(DO_WITH_SPRING);
BeanBuilder bb = new BeanBuilder(getParentCtx(), application.getClassLoader());
bb.setSpringConfig(springConfig);
Binding b = new Binding();
b.setVariable("application", application);
b.setVariable("manager", getManager());
b.setVariable("plugin", this);
b.setVariable("parentCtx", getParentCtx());
b.setVariable("resolver", getResolver());
bb.setBinding(b);
c.setDelegate(bb);
bb.invokeMethod("beans", new Object[]{c});
}

}
//动态配置plugin,调用plugin的doWithApplicationContext方法
public void doWithApplicationContext(ApplicationContext applicationContext)

FiltersGrailsPlugin.groovy

def watchedResources = "file:./grails-app/conf/**/*Filters.groovy"
//Spring bean DSL
static final BEANS = { filter ->
"${filter.fullName}Class"(MethodInvokingFactoryBean) {
targetObject = ref("grailsApplication", true)
targetMethod = "getArtefact"
arguments = [TYPE, filter.fullName]
}
"${filter.fullName}"(filter.clazz) { bean ->
bean.singleton = true
bean.autowire = "byName"
}
}
//生成了实现spring HandlerInterceptor接口的filterInterceptor
def doWithSpring = {
filterInterceptor(org.codehaus.groovy.grails.plugins.web.filters.CompositeInterceptor) {

}

for(filter in application.getArtefacts(TYPE)) {
def callable = BEANS.curry(filter)
callable.delegate = delegate
callable.call()
}
}

def doWithApplicationContext = { applicationContext ->
reloadFilters(application, applicationContext)
}


// 把Filters groovy类变成CompositeInterceptor的handlers成员
// 用FilterToHandlerAdapter适配器把preHandle==before,postHandle==after,afterCompletion==afterView对应起来
private reloadFilters(GrailsApplication application, applicationContext) {
log.info "reloadFilters"
def filterConfigs = application.getArtefacts(TYPE)
def handlers = []
for(c in filterConfigs) {
def filterClass = applicationContext.getBean("${c.fullName}Class")
def bean = applicationContext.getBean(c.fullName)
for(filterConfig in filterClass.getConfigs(bean)) {
handlers << new FilterToHandlerAdapter(filterConfig:filterConfig, configClass:bean)
}
}

if (log.isDebugEnabled()) log.debug("resulting handlers: ${handlers}")
applicationContext.getBean('filterInterceptor').handlers = handlers
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值