一、GroupTemplateFactroyBean与Beetl Spring扩展类

  本章主要介绍GroupTemplateFactroyBean及其相关的Beetl Spring扩展类,这些类的设计目的均为尽可能将Beetl所使用的各种组件对象(Function,ResourceLoader,TagFactory,甚至核心对象GroupTemplate等都交由Spring容器管理,以充分利用Spring的特性增强组件功能,这一思想是后面Beetl对Spring MVC及Spring Security整合的基础),除非有特殊需要,这些扩展并不要求Web环境,即使为普通的Spring应用程序的也能使用。

  文中涉及的Beetl的相关概念请阅读Beetl文档:http://ibeetl.com/guide/

1.1 GroupTemplateFactroyBean

  GroupTemplate是Beetl的核心配置和操作类,对模板的渲染以及模板配置都是以此类为中心实现的。GroupTemplateFactoryBean是一个Spring FactoryBean<GroupTemplate>,用以在指定配置后构造GroupTemplate实例。将他配置为一个Spring Bean,如下:

<bean name="groupTemplate" class="org.fox.beetl.ext.spring.GroupTemplateFactoryBean"/>

  GroupTemplateFactoryBean的所有配置参数都是可选的,他们可以对GroupTemplate细节提供细化的配置,具体参数格式见下表:

参数名 参数类型
说明
 configFileResource  Resource

指定Beetl配置文件,这使用Spring IO包的Resource的语法来指定资源

默认情况下加载Beetl包自带的默认配置文件:

classpath:org/beetl/core/beetl-default.properties

 configProperties  Properties 用于覆盖上述配置文件中配置项的Properties
 resourceLoader  ResourceLoader

Beetl组件:资源加载器,负责按照给定path加载模板数据

默认Beetl会按照配置文件指定自己实例化资源加载器

(Beetl默认使用ClassPathResourceLoader从classpath中获取模板)

 errorHandler  ErrorHandler

Beetl组件:错误处理器,负责对Beetl模板渲染过程中出现的错误进行处理

默认Beetl会按照配置文件指定自己实例化错误处理器

(Beetl默认将错误输出到Stdout中)

 sharedVars  Map<String, Object> Beetl模板的共享变量,所有该GroupTemplate实例处理的模板都能使用该实例
 extGroupTemplateConfigs  List<ExtGroupTemplateConfig>

GroupTemplate扩展配置类,他能对本属性以下的所有属性进行额外设置,他主要为更多配置扩展进行简化的统一配置支持

默认不设置时,GroupTemplateFactoryBean会自动检测上下文中所有已经部署的ExtGroupTemplateConfig实现Bean进行配置。

注意1:本属性及本属性以上的配置不能被ExtGroupTemplateConfig设置,即configFileResource、configProperties、resourceLoader、errorHandler、sharedVars、extGroupTemplateConfigs这几个属性必须在GroupTemplateFactoryBean中设置;

注意2:配置顺序按照列表给定的顺序执行,最后是当前GroupTemplateFactoryBean的自身设置,如果配置冲突以最后配置为准。

例如Beetl Spring Security整合扩展提供预设的整合配置文件,security-ext.3.2.xml,将扩展的tag和function都配置为一个ExtGroupTemplateFactory实例,这样使用时只需要在当前配置文件中import入预设文件,将对应的ExtGroupTemplateFactory实例就

用法参考beetl-spring-web-security-example示例

 functions  Map<String, Function>

Beetl组件:自定义函数

其中key为函数名

 typeFormats  Map<Class<?>, Format>

Beetl组件:自定义类型默认格式化器

其中key为类型Class

 formats  Map<String, Format>

Beetl组件:自定义格式化器

其中key为格式化器名

 tagFactorys  Map<String, TagFactory>

Beetl组件:自定义标签(工厂)

其中key为标签名

 functionPackages  Map<String, Object>

Beetl组件:自定义函数包

其中key为函数包名

 virtualClassAttributes  Map<Class<?>, VirtualClassAttribute>

Beetl组件:为类型添加自定义虚拟属性

其中key为类型Class

 virtualAttributeEvals  List<VirtualAttributeEval>

Beetl组件:虚拟属性执行器

与virtualClassAttributes不同,他们不特定于某个类型

 1.2 SpElFunction

  SpELFunction函数类是Beetl的一个Function扩展,执行一个SpEL表达式返回其结果,调用格式为:

Object spel(String expression)

  SpEL表达式的相关内容请参见Spring文档,它在一般EL语法上进行扩展,允许直接调用对象函数,提供对集合类的投影,筛选操作等。特殊的可以在SpEL表达式中使用@beanName的的方式直接引用到Spring上下文中的Bean,也允许使用T(className).method()调用指定类型的静态函数。例如:

1 spel("@urlEncoder.encode(name)");
2 spel("T(java.util.UUID).randomUUID().toString()");

  注意1:由于Beetl的限制,当前版本的SpELFunction只支持操作Beetl上下文中的共享变量和全局变量,并不支持;

  注意2:SpELFunction必须作为Spring上下文中的受管Bean通过GroupTemplateFactoryBean提供给Beetl使用。

1.3 SpringServletContextResourceLoader

  SpringServletContextResourceLoader使用Spring的机制获取Web环境中的ServletContext,以servletContext.getRealPath("/")获取到的文件路径为资源的根目录。这个ResourceLoader用以在Spring Web环境下替换Beetl自带的WebAppResourceLoader,以解决Beetl的jar包不在WEB-INF/lib下造成错误判定WebRoot目录的问题(例如main方法启动的Jetty服务)。

  注意1:与一般基于File的FileResourceLoader相同,他支持设置charset和autoCheck属性,但它不支持设置root属性(只能通过beetl配置文件REOURCE.root设置)。

  注意2:SpringServletContextResourceLoader必须作为Spring上下文中的受管Bean通过GroupTemplateFactoryBean提供给Beetl使用。

1.4 SpringBeanTagFactory

  SpringBeanTagFactory作为一个TagFactory实现,他按照name参数的设置,从Spring上下文中获取指定name的Tag实现Bean实例返回。SpringBeanTagFactory必须作为Spring上下文中的受管Bean通过GroupTemplateFactoryBean提供给Beetl使用。并且应该保证他所引用的Tag实现Bean必须是prototype的,不能单例,否则在使用时会出现不一致的情况。

 1 <bean name="groupTemplate" ....>
 2   <property name="tagFactorys">
 3     <map>
 4       <entry key="sec.accessIf" value-ref="accessIfTagFactory"/>
 5     </map> 
 6   </property>
 7 </bean>
 8 <bean name="accessIfTagFactory" class="org.fox.beetl.ext.spring.tag.SpringBeanTagFactory">
 9     <property name="name" value="accessIfTag"/>
10 </bean>
11 <bean name="accessIfTag" class="...." scope="prototype"/>

  截至Beetl2.0.10,SpringBeanTagFactory的使用有一些特殊问题,需要一些特殊处理技巧,详细问题描述和处理技巧参见这里:http://www.cnblogs.com/shishuifox/p/3852398.html  使用方法建议参考示例beetl-spring-web-security-example

  简单的说,要正常使用SpringBeanTagFactory,需要保证1. 将他定义为一个公开的有确认名字的bean,不能使用匿名bean或内部bean定义。2.在应用程序上下文中注册一个ApplicationContext生命周期监听器:

<bean class="org.fox.beetl.ext.spring.utils.ApplicationContextLifecycleEventListener"/>

  Beetl2.0.11已经修正该问题,该限制也于beetl-spring.1.0.4取消,建议升级。