加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

GRAILS框架运行机制探

发布时间:2020-12-14 17:08:47 所属栏目:大数据 来源:网络整理
导读:grails提供了一个基于约定的MVC web框架。那么,这个框架是如何运作的呢? 我们知道grails框架提供了DSL风格的控制器和高度简化的domain,框架几乎帮我们做了所有的事情,我们仅仅集中精力到业务上。 框架做了以下的工作 1,整个MVC流程的运转(这个大家很熟
grails提供了一个基于约定的MVC web框架。那么,这个框架是如何运作的呢?
我们知道grails框架提供了DSL风格的控制器和高度简化的domain,框架几乎帮我们做了所有的事情,我们仅仅集中精力到业务上。
框架做了以下的工作
1,整个MVC流程的运转(这个大家很熟,多数MVC框架都提供)
2,DSL风格的控制器(动态增强)
3,增强的domain

查看了grails的代码,知道grails是通过springmvc来实现grails框架的,不同的地方,在得到control以后,grails利用groovy语言的动态能力对control进行了增强。

GORM的增强时比较有意思的。
grails通过加载sessionfactorybean的时候(ConfigurableLocalSessionFactoryBean),会依次生成sessionfacoty和domainclass,并且利用spring的beanaware能力,在GORMEnhancingBeanPostProcessor的postProcessAfterInitialization方法中,
DomainClassGrailsPlugin.enhanceDomainClasses(application,applicationContext)
HibernatePluginSupport.enhanceSessionFactory(sf,application,applicationContext)


static enhanceDomainClasses(GrailsApplication application,ApplicationContext ctx) {
        for(GrailsDomainClass dc in application.domainClasses) {
			def domainClass = dc
            MetaClass metaClass = domainClass.metaClass

            metaClass.ident = {-> delegate[domainClass.identifier.name] }
            metaClass.constructor = {->
                if(ctx.containsBean(domainClass.fullName)) {
                    ctx.getBean(domainClass.fullName)
                }
                else {
                    BeanUtils.instantiateClass(domainClass.clazz)
                }
            }
            metaClass.static.create = {-> ctx.getBean(domainClass.getFullName()) }

            addValidationMethods(application,domainClass,ctx)
            addRelationshipManagementMethods(domainClass)
        }
    }

另外,HibernatePluginSupport是作为插件加载的,但是现在很多代码写死在grails里的,因此GORM现在和hibernate是强耦合的(我看了,代码写的一团浆糊,解耦的话估计工作量不小)

grails的插件运行机制是DefaultGrailsPlugin载入所有插件,//调用plugin的doWithSpring方法,加载plugin到spring的ApplicationContext

   def doWithSpring = {  .....  }


 Closure c = (Closure)this.plugin.getProperty(DO_WITH_SPRING);
            BeanBuilder bb = new BeanBuilder(getParentCtx(),springConfig,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 Object[]{c});
     


doWithSpring是委托执行,委托beanbuilder执行闭包
	private BeanBuilder invokeBeanDefiningClosure(Closure callable) {

		callable.setDelegate(this);
  //      callable.setResolveStrategy(Closure.DELEGATE_FIRST);
        callable.call();
		finalizeDeferredProperties();

        return this;
    }

doWithApplicationContext是直接执行,参数是applicationContext
    public void doWithApplicationContext(ApplicationContext applicationContext) {
        if(this.pluginBean.isReadableProperty(DO_WITH_APPLICATION_CONTEXT)) {
            Closure c = (Closure)this.plugin.getProperty(DO_WITH_APPLICATION_CONTEXT);
            c.setDelegate(this);
            c.call(new Object[]{applicationContext});
        }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读