友好的开发框架-Asta4D(5):视图优先的URL映射以及变量注入

1. 视图优先

在Asta4D中,遵循的是视图优先(View First)的原则,而不是传统的MVC架构,URL规则声明不需要声明Cotroller,一个URL可以直接映射一个模板文件--视图优先:)

Asta4D的URL映射规则不是通过配置文件来定义的,框架通过一组易于试用的API构建了一套DSL来帮助定义URL规则,也就是说,Asta4D的URL规则声明是可编程,相对于基于配置文件的声明方式,这提供了更多的弹性。

Asta4D提供了一个接口:UrlMappingRuleInitializer,用户通过实现该接口来声明自己的URL规则:

public class UrlRules implements UrlMappingRuleInitializer {  
  
    @Override  
    public void initUrlMappingRules(UrlMappingRuleHelper rules) {  
        //@formatter:off  
        rules.add(GET, "/")  
             .redirect("/app/index");  
          
        rules.add(GET, "/redirect-to-index")  
             .redirect("p:/app/index");  
          
        rules.add("/app/", "/templates/index.html");  
        rules.add("/app/index", "/templates/index.html");  
        rules.add("/app/{name}/{age}", "/templates/variableinjection.html");  
        ...  
  
        //@formatter:on  
    }  
  
}  

2. 映射规则声明的语法与路径变量的声明

Asta4D的规则映射语法基本上是参照Spring MVC的URL映射规则实现的,声明的路径中,用花括号包起来的部分将被解释为路径变量,并在稍后的处理逻辑中可以引用到。 

同时,在声明URL映射规则的时候,可以通过下面的语法声明额外的路径变量:

rules.add("/app/{name}/{age}", "/templates/variableinjection.html")
     .var("extraId", 1234);

3. 变量注入

Asta4D实现了跟Spring MVC及其类似的变量注入机制,在snippet class的实现中,实例变量以及方法的参数的值,都由框架自动注入。

在Asta4D中,snippet class的实例是在每一个request中单子化的,即无论一个snippet class被引用多少次,在一个request中只会维持一个实例。我们来看看下面的snippet class:

public class InitSnippet implements InitializableSnippet {  
  
        @ContextData  
        private String value; // (1)  
        private long id;  
        private String resolvedValue;  
        private int count = 0;  
  
        @Override  
        public void init() throws SnippetInvokeException { //(2)  
            resolvedValue = value + "-resolved";  
            count++;  
        }  
        @ContextData  
        private void setId(long id) { //(3)  
            this.id = id;  
        }  
        public Renderer render_1() {  
            return Renderer.create(".value", resolvedValue)  
                           .add(".count", count);  
        }  
        public Renderer render_2() {  
            return Renderer.create(".value", resolvedValue)  
                           .add(".count", count);  
  
        }  
         
        // (4)  
        public Renderer getPathVarName(  
        @ContextData(name = "count", scope = WebApplicationContext.SCOPE_PATHVAR)  
        int count) {  
        }  
  
        // (5)  
        public Renderer getQueryParamName(  
        @ContextData(name = "var", scope = WebApplicationContext.SCOPE_QUERYPARAM)  
        String name) {  
        }  
  
        // (6)  
        public Renderer getDefaultName(String name) {  
        }  
    }  

(1)声明了名为value的变量,@ContextData表明该变量需要在snippet类实例化时接受注入

(2)实现了InitializableSnippet接口的init方法,这个接口不是必须的,但实现了该接口的snippet class,在所有实例变量被注入结束后,init方法会被调用一次来实现自定义的初始化逻辑

(3)setter方法上同样可以通过@ContextData来声明实例变量的注入

(4)snippet方法上的变量注入声明,注意,这里用name和scope额外声明了该变量的查找名字以及查找scope:在路径变量中查找名为count的变量

(5)仍然是snippet方法上的变量注入声明:在request parameter中查找名为var的变量,注意,这里查找的变量名与实际声明的方法的参数名是不一致的。

(6)snippet方法上的简单变量注入声明,既没有名字,也没有scope,和(1),(3)的例子相同,在没有声明名字的时候,查找的变量名字将使用声明的变量的名字,而没有声明scope的时候,将按照下述的顺序进行查找:

  • html tag属性,一直上溯到最外层的html tag(该scope只对snippet方法有效)
  • 路径变量(path var)
  • request parameter
  • flash var(redirect时跨请求传递的变量)
  • cookie
  • request header
  • request attribute
  • session
  • global(框架维护的一个全局静态变量池)

额外说明的是, 这个顺序可以在框架启动的时候通过WebApplicationConfiguration进行修改。

猜你喜欢

转载自xzer.iteye.com/blog/1998884