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是如何处理工件再做分析

你可能感兴趣的:(框架,xml,Web,grails,groovy)