grails提供了
一个基于约定的MVC web框架。那么,这个框架是如何运作的呢?
我们知道grails框架提供了DSL风格的控制器和高度简化的domain,框架几乎帮我们
做了所有的事情,我们仅仅集中精力到业务上。
框架
做了以下的工作
1,整个MVC流程的运转(这个大家很熟,多数MVC框架都提供)
2,DSL风格的控制器(动态增强)
3,增强的domain
查看了grails的
代码,知道grails是通过springmvc来实现grails框架的,不同的地方,在得到control以后,grails利用groovy语言的动态能力对control进行了增强。
GORM的增强时比较有意思的。
grails通过加载session
factorybean的时候(Con
figurableLocalSession
factorybean),会依次
生成sessionfacoty和domainclass,并且利用spring的beanaware能力,在GORMEnhancingBeanPostProcessor的postProcessAfterInitialization
方法中,
@H_
450_15@
DomainClassGrailsPlugin.enhanceDomainClasses(application,applicationCo
ntext)
HibernatePluginSupport.enhanceSessionFactory(sf,application,applicationCo
ntext)
@H_
450_15@static enhanceDomainClasses(GrailsApplication application,ApplicationCo
ntext ct
X) {
for(GrailsDomainClass dc in application.domainClasses)
{
def domainClass = dc
MetaClass
MetaClass = domainClas
s.MetaClass
MetaClas
s.ident =
{-> delegate[domainClas
s.identifier.name] }
MetaClas
s.constructor =
{->
if(ctx.containsBean(domainClas
s.full
Name))
{
ctx.getBean(domainClas
s.full
Name)
}
else
{
BeanUtil
s.instantiateClass(domainClas
s.claz
z)
}
}
MetaClas
s.static.create =
{-> ctx.getBean(domainClas
s.getFullName()) }
addValidationMethods(application,domainClass,ct
X)
addRelationshipManagementMethods(domainClass)
}
}
另外,HibernatePluginSupport是作为
插件加载的,但是现在很多
代码写死在grails里的,因此GORM现在和hibernate是强耦合的(我看了,
代码写的一团浆糊,解耦的话估计工作量不小)
grails的
插件运行机制是DefaultGrailsPlugin载入所有
插件,//
调用plugin的doWithSpring
方法,加载plugin到spring的ApplicationCo
ntext
@H_
450_15@ def doWithSpring =
{ ..... }
@H_
450_15@
Closure c = (Closur
E)thi
s.plugin.getProperty(DO_WITH_SPRING
);
BeanBuilder bb = new BeanBuilder(getParentCtx(),springCon
fig,application.getClassLoader()
);
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 Ob
ject[]
{C}
);
doWithSpring是委托执行,委托beanbuilder执行闭包
@H_
450_15@
private BeanBuilder invokeBeanDefiningClosure(Closure callabl
E) {
callable.setDelegate(this
);
// callable.setResolveStrategy(Closure.DELEGATE_FIRST
);
callable.call(
);
finalizeDeferredProperties(
);
return this;
}
doWithApplicationCo
ntext是直接执行,参数是applicationCo
ntext
@H_
450_15@
public void doWithApplicationCo
ntext(ApplicationCo
ntext applicationCo
ntext)
{
if(thi
s.pluginBean.isReadableProperty(DO_WITH_APPLICATION_CO
ntexT))
{
Closure c = (Closur
E)thi
s.plugin.getProperty(DO_WITH_APPLICATION_CO
ntexT
);
c.setDelegate(this
);
c.call(new Ob
ject[]
{applicationCo
ntext}
);
}