`
bloodwolf_china
  • 浏览: 129922 次
社区版块
存档分类
最新评论

grails基本框架

阅读更多
   使用grails开发已经有一段时间,中间遇到不少问题,由于grails本身提供的文档有点简单,某些功能实现还须参考其源码。在分析过程中逐渐了解其运行构架,稍做介绍。
grails框架是根据约定优于配置这条原则搭建,MVC部分是基于Spring MVC,持久层是基于hibernate。查看打包后的文件目录,找到WEB-INF/web.xml,可以发现核心的几个配置

<filter>
  <filter-name>urlMapping</filter-name> 
  <filter-class>org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter</filter-class> 
</filter>

<filter-mapping>
  <filter-name>urlMapping</filter-name> 
  <url-pattern>/*</url-pattern> 
  </filter-mapping>


<servlet>
  <servlet-name>grails</servlet-name> 
  <servlet-class>org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet</servlet-class> 
  <load-on-startup>1</load-on-startup> 
</servlet>

<servlet-mapping>
  <servlet-name>grails</servlet-name> 
  <url-pattern>*.dispatch</url-pattern> 
</servlet-mapping>

urlMapping filter的作用是根据request uri查找到相应的grails controller的处理路径,然后forward到/grails/controller/action.dispatch,这样就
把请求转到了GrailsDispatcherServlet来处理,调用controller的各种拦截器,处理逻辑,并返回view。
在看看WEB-INF目录下还有两个重要的配置文件,applicationContext.xml和grails.xml
applicationContext.xml,加载grails各种工件(Artefact)和插件(plugin)
<bean id="grailsApplication" class="org.codehaus.groovy.grails.commons.GrailsApplicationFactoryBean">
		<description>Grails application factory bean</description>
        <property name="grailsDescriptor" value="/WEB-INF/grails.xml" />
        <property name="grailsResourceLoader" ref="grailsResourceLoader" />
	</bean>

grails.xml:又grails命令生成,包含grails工件和插件
<grails>
  <resources>
    <resource>ApplicationFilters</resource>
    <resource>BootStrap</resource>
    <resource>Config</resource>
    <resource>DataSource</resource>
    <resource>resources</resource>
    <resource>UrlMappings</resource>
    <resource>MagazineBusinessController</resource>
    <resource>BusinessSmsLog</resource>
    <resource>MonthBusinessChargeJob</resource>
    <resource>SmsChargeService</resource>
    <resource>MagazineBusinessService</resource>
    <resource>XMLCodec</resource>
    <resource>DefaultQuartzConfig</resource>
    <resource>QuartzBootStrap</resource>
    <resource>JobManagerController</resource>
    <resource>JobManagerService</resource>
  </resources>
  <plugins>
    <plugin>QuartzGrailsPlugin</plugin>
    <plugin>RemotingGrailsPlugin</plugin>
  </plugins>

grails中包含以下几种工件
DomainClass Artefact(Domain模型工件),Controller Artefact(Controller工件),Service Artefact(Service工件),TagLib Artefact(工件),Bootstrap ArtefactHandler(初始化启动工件),
Codec Artefact(Codec工件),UrlMappings Artefact(UrlMapping工件),Filters Artefact(过滤拦截工件)

GrailsApplicationFactoryBean的代码
public void afterPropertiesSet() throws Exception {
        if(descriptor != null && descriptor.exists()) {
            // Enforce UTF-8 on source code for reloads
            CompilerConfiguration config = CompilerConfiguration.DEFAULT;
            config.setSourceEncoding("UTF-8");

            GroovyClassLoader classLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
            List classes = new ArrayList();
            SAXReader reader = new SAXReader();
            InputStream inputStream = null;
            try {
                inputStream = descriptor.getInputStream();
                Document doc = reader.read(inputStream);
                List grailsClasses = doc.selectNodes("/grails/resources/resource");
                for (Iterator i = grailsClasses.iterator(); i.hasNext();) {
                    Node node = (Node) i.next();
                    try {
                        classes.add(classLoader.loadClass(node.getText()));
                    } catch (ClassNotFoundException e) {
                        LOG.warn("Class with name ["+node.getText()+"] was not found, and hence not loaded. Possible empty class or script definition?");
                    }
                }
            } finally {
                if(inputStream!=null)
                    inputStream.close();
            }
            Class[] loadedClasses = (Class[])classes.toArray(new Class[classes.size()]);
            this.grailsApplication = new DefaultGrailsApplication(loadedClasses, classLoader);
        }
        else {
            Assert.notNull(resourceLoader, "Property [resourceLoader] must be set!");

            this.grailsApplication = new DefaultGrailsApplication(this.resourceLoader);
        }

        ApplicationHolder.setApplication(this.grailsApplication);
    }

GrailsApplicationFactoryBean已经把grails.xml中所有的grails工件类加载了进来,保存在DefaultGrailsApplication中
DefaultGrailsApplication的代码
public DefaultGrailsApplication(final Class[] classes, GroovyClassLoader classLoader) {
        ...
        this.allClasses = classes;
        this.cl = classLoader;
        this.applicationMeta = loadMetadata();//读取WEB-INF/classes下application.properties配置
}

private void initArtefactHandlers() {
        registerArtefactHandler(new DomainClassArtefactHandler());
        registerArtefactHandler(new ControllerArtefactHandler());
        registerArtefactHandler(new ServiceArtefactHandler());
        registerArtefactHandler(new TagLibArtefactHandler());
        registerArtefactHandler(new BootstrapArtefactHandler());
        registerArtefactHandler(new CodecArtefactHandler());
        registerArtefactHandler(new UrlMappingsArtefactHandler());

        // Cache the list as an array
        this.artefactHandlers = ((ArtefactHandler[]) this.artefactHandlersByName.values().toArray(
                new ArtefactHandler[artefactHandlersByName.size()]));
}

public boolean isArtefact(Class theClazz) {
        String className = theClazz.getName();
        for (Iterator i = allArtefactClasses.iterator(); i.hasNext();) {
            Class artefactClass = (Class) i.next();
            if (className.equals(artefactClass.getName())) {
                return true;
            }
        }
        return false;
    }

就此分析GrailsApplication接口代表是应用中所有的工件,而ArtefactHandler是工件接口
public interface GrailsApplication extends ApplicationContextAware {

	public Class[] getAllClasses();
	public Class[] getAllArtefacts();
	public boolean isArtefact(Class theClazz);
}

public interface ArtefactHandler {
    boolean isArtefact(Class aClass);
    GrailsClass newArtefactClass(Class artefactClass);
}


待续,后面准备就UrlMapping机制看看grails是如何处理工件再做分析
3
1
分享到:
评论
1 楼 shiren1118 2009-01-09  
不错,分析的很好,继续~

相关推荐

    grails框架

    实际上,一个grails插件和一个grails应用基本是完全一样的,同样可以使用grails run-app命令来运行。区别仅在于一个插件的根目录下需要提供一个fooplugin.groovy文件,提供插件的一些描述信息。

    LittleGoblin:用Grails编写的浏览器游戏框架

    Little Goblin v 0.5.2的发行说明Little Goblin是一个使用Graovy,Java和JavaScript用Grails框架编写的浏览器游戏框架。 它包括一个用于测试和演示的参考实现,它将创建一个基本的可用游戏环境,如上的测试服务器所...

    玩转JavaWeb应用开发:Play框架

    Play框架在设计的时候借鉴了流行的RubyonRails和Grails等框架,又有自己独有的优势。使用Play框架可以方便和高效的开发出JavaWeb应用。通过Play框架提供的命令行工具,可以快速的创建出一个Web应用的基本骨架。它的...

    SpringData.zip

    支持 Oracle RAD、高级队列和高级数据类型JPA - 简化创建 JPA 数据访问层和跨存储的持久层功能Mapping - 基于 Grails 的提供对象映射框架,支持不同的数据库Examples - 示例程序、文档和图数据库Guidance - 高级...

    spring boot 实战,springboot实战项目,Java

    讲到Groovy,第6章会介绍Grails 3,这是Grails框架的最新版本,它基于Spring Boot。? 在第7章里你将看到如何通过Spring Boot的Actuator了解运行中的应用程序,以及它是如何工作的。你还会看到如何使用Actuator的Web...

    SpringBoot实战第4版清晰版

     讲到Groovy,第6章会介绍Grails 3,这是Grails框架的最新版本,它基于Spring Boot。  在第7章里你将看到如何通过Spring Boot的Actuator了解运行中的应用程序,以及它是如何 工作的。你还会看到如何使用Actuator...

    spring data API

    Mapping - 基于 Grails 的提供对象映射框架,支持不同的数据库 从之前发布其他chm文件下载用户的反映看,有不少朋友反映下载后打开无法显示,这一般不是chm文件的问题,这里统一说明一下解决办法: 如果文件打开...

    毕业设计论文+源程序代码(企业人事管理系统)

    用的是grails1.3.7的框架。。 里面pms war包直接部署tomcat下可运行。 开发工具:SpringSource Tool Suit9.2、JDK6.0 开发语言:Java、Groovy、Html、Javascript 本系统主要完成对企业员工考勤的统计和管理:对各...

    ckeditor:用于导轨的Ckeditor 4.x集成gem

    特征CKEditor版本4.x( ) Rails 5.x,4.2.x集成文件浏览器HTML5文件上传器用于formtastic和simple_form表单生成器的钩子与授权框架和集成安装对于基本用法,只需包含ckeditor gem: gem 'ckeditor'或者,如果您想...

    java版斗地主源码-frontEndCourse:分享对于前端技术的理解和一些技术演示

    java版斗地主源码 ...基本上大部分技术方向上每年都会出不少新东西,想精通一项技术,然后一 招鲜吃遍天,恐怕不太现实。 二,技术方向的演变方向不容易预见。兄弟我就遇到过这个困惑。想当年在IBM主机开

Global site tag (gtag.js) - Google Analytics