依赖项与扩展点
依赖项
定义一个依赖项方法的语法格式如下:
@_Dependency(alias="别名"【可选,当没有给出alias时方法名及依赖项的名称】)
public|protected abstract 返回参数 方法名(入口参数表) 抛出异常列表;
如:
@_Dependency
protected abstract I_DataSource getDataSource(String _dsType) throws ThrowAble;
或者在*.ria.xml中定义,如(下例为扩展点定义,依赖项)
<?xml version="1.0" encoding="UTF-8"?> <prolet id="websinger" title="网站管理系统(CMS)" parent="cloudsinger.cloudApps" view="main.aq.html" class="MainBiz" icon16="icon16.gif" icon32="icon32.gif"> <subpro id="welcome" title="欢迎使用" view="welcome.aq.html" /> <subpro id="page" title="页面属性" view="profile.aq.html" class="ProfileBiz"> <subpro id="preview" title="页面预览" view="preview.aq.html" class="PreviewBiz" /> <subpro id="contentEditor" title="页面内容编辑" view="editor.aq.html" class="EditorBiz" /> </subpro> <subpro id="weblet" title="WEB小应用程序" icon16="weblet16.gif" /> <subpro id="defaultWeblet" title="Websinger提供的Weblet" class="MainBiz"> <subpro id="html" title="自定义HTML板块" view="html.aq.html" class="HtmlBiz"> <subpro id="editor" title="HTML编辑器" view="htmlEdit.aq.html" class="HtmlEditBiz" /> </subpro> <junction from="this:getWeblets" to="cloudsinger.cloudApps/websinger:getWebletBean" /> </subpro> <!--依赖项 --> <dependency id="getWebletBean" title="获取WebletBean"> <output type="org.cloudsinger.cloudApps.websinger.page.contentEditor.WebletBean" desc="支持多重扩展" /> </dependency> </prolet>
注意:
1)依赖项的访问控制符至少为protected,不能采用默认或者private;
2)依赖项可以在@_Dependency中以name给出依赖项的名称,这一点在同一ProletBean中存在多个同名方法时非常有用,默认情况下,
依赖项的名称为方法名;
3)当依赖项方法为非abstract方法时,若该依赖项没有被满足,则默认返回方法中的结果(即默认的实现),
这一点在单元测试时显得尤为重要;
4)ToyBricks体系支持“一个依赖项多次实现”,此时依赖项的返回应为java.util.Vector类型,如:
/**
* 【依赖项】扩展资源
*
* @return
*/
@_Dependency
protected Vector<ResourcePlusBean> getResourcePlusBean() {
return null;
}
扩展点
扩展点的语法与依赖项完全相同。两者的区别在于:依赖项“必须被满足”而扩展点则不同
RIA体系提供的默认依赖项实现及实现自定义的默认依赖项
org.cloudsinger.ria.api.I_ProletContext
返回类型org.cloudsinger.ria.api.I_ProletContext的依赖项由RIA引擎默认实现,如:
public NavigationBean getTopicTreeDS() {
NavigationBean root = NavigationBean.getRootNode("toybricks",
"ToyBricks(积木)开发平台", getContext().getLafPath()
+ "/toybricks16.gif");
@_Dependency
protected abstract I_ProletContext getContext();
注意:
I_ProletContext接口为RIA API中提供的重要的接口,其提供了大量常规的方法,如getRequest、getContextPath
等等方法,在编程时,只需要声明该依赖项即可直接使用,这为编程带来了极大的便利;
实现自定义的默认依赖项
您可能会在您的体系下实现某接口的默认实现,则您会用到Annotation:org.cloudsinger.toybricks.api._ImplementBy,
您需要以下两个步骤:
1)声明“默认依赖项”返回的接口,在接口上添加注释org.cloudsinger.toybricks.api._ImplementBy,给出默认的实现Factory,如:
@_ImplementBy(ProletContextFactory.class)
public interface I_ProletContext extends I_ComponentContext {
ToyBricks getToyBricks();
2)实现默认的Factory;如:
public class ProletContextFactory implements I_ImplementFactory{
public I_ProletContext product(I_ComponentPrototype _com) {
return (I_ProletContext)_com.$getContext();
}
}
ProletBean的关系编织
除在ria.xml中描述组件关系之外,ProletBean中亦可以通过org.cloudsinger.toybricks.api._JunctionTo来注释实现,如:
@_JunctionTo(value = "this.topicTree:getDataSource")
public NavigationBean getTopicTreeDS() {
NavigationBean root = NavigationBean.getRootNode("toybricks",
"ToyBricks(积木)开发平台", getContext().getLafPath()
+ "/toybricks16.gif");
I_ProletRegister reg = getContext().getProletRegister();
List<I_ProletRegister> chd = (List<I_ProletRegister>) reg
.getChildrenAsList();
if (chd != null) {
for (I_ProletRegister r : chd) {
if (!r.getId().equals("welcome")) {
_in(root.addChild(r.getPath(), r.getTitle()), r);
}
}
}
return root;
}
视图的源代码:
<script>
function openTopic(){
var node = $.com("topicTree").focusNode();
if(!node.isRoot()){
$.com("tabs").addTab(node.id,node.title,node.id);
}
}
</script>
<cs:Splitter id="tabPanel" style="width:100%;height:100%;">
<cs:col style="width:200px">
<cs:Tree id="topicTree" onNodeDblclick="openTopic"/>
</cs:col>
<cs:col>
<cs:TabBox id="tabs" style="width:100%;height:100%;">
<cs:tab title="欢迎使用" proletPath="welcome" />
</cs:TabBox>
</cs:col>
</cs:Splitter>
上例中描述了在ProletBean中的方法“getTopicTreeDS”满足(JunctionTo)当前页面中id为“topicTree”组件的依赖项“getDataSource”。 以下是对依赖项“视图中的topicTree组件的getDataSource”满足的等价写法:
@_JunctionTo(value = "this/tabPanel/topicTree:getDataSource")
public NavigationBean getTopicTreeDS() {
//...
}
及
@_JunctionTo(value = "view/tabPanel/topicTree:getDataSource")
public NavigationBean getTopicTreeDS() {
//...
}
在RIA体系下,视图中的组件(表现为标签(忽略属性标签),根组件为window组件)的结构构成一棵树,在本例中,组件(id=topicTree)的层次关系为:
window组件/tabPanel/topicTree
以上三种写法的区别是:
1)this.topicTree指明当前Prolet下的id为topicTree的组件(不论该组件位于窗体下组件哪个层次);
2)view/tabPanel/topicTree指明当前Prolet下,视图(view)窗体组件下id为tabPanel的组件下的id为topicTree的组件;
3)同2);
注意,ProletBean中的编织(@_JunctionTo)建议锁定在Prolet内部(如上例中ProletBean的方法满足视图中组件的依赖项),Prolet之间 的编织关系建议写在ria.xml中。
本文深入解读ToyBricks体系中的依赖项与扩展点的概念、语法格式及应用实例,包括如何在RIA体系下实现默认依赖项、自定义依赖项,以及ProletBean中的关系编织和视图组件依赖项的满足方式。
2万+

被折叠的 条评论
为什么被折叠?



