SCA/Tuscany的一些使用心得(二) -DefaultSCADomain与组合构件(composite)
DefaultSCADomain是多数用于测试使用域,上回SCADomain的源码,默认就会走此实现,
此类针对贡献包,复合组件,组件进行初始化至内存之中;
SCADomain调用:
// 创建默认的实现
domain = new DefaultSCADomain(runtimeClassLoader, applicationClassLoader, domainURI, contributionLocation,composites);
// runtimeClassLoader - 域的classLoader(没用)
// applicationClassLoader - 应用的classLoader,主要使用此classLoader运行;
// domainURI - 默认是"http://localhost"
// contributionLocation - 贡献包路径,默认是"/"
// composites - 默认测试是只能编写一个composite配置文件,而DefaultSCADomain构造函数是多参的;
DefaultSCADomain:
本对象涉及SCANode和SCAClient,ComponentManager,这里一笔带过,后面会讲解,本次主要叙述本类层次的主流程,
话说回来,源码是要层层的看,当然这是要了解结构和生命周期的读法,debug还是定位到类去看,哈哈;
1.初始化所需的参数:
1.1 处理传参
this.uri = domainURI;
this.composites = composites;
this.applicationClassLoader = applicationClassLoader;
this.domainURI = domainURI;
this.composites = composites;
this.componentManager = new DefaultSCADomainComponentManager(this);
1.2 默认没有贡献包,创建一个贡献包URL集合
this.contributionURLs = new ArrayList<String>();
if (contributionLocation != null && !"/".equals(contributionLocation)) { // 默认没有贡献包,创建;
this.contributionURLs.add(contributionLocation);
}
2.初始化环境:
2.1 创建SCANODE工厂
SCANodeFactory factory = SCANodeFactory.newInstance();
2.2 根据compusite创建SCANodeImp
规则 : 如果拥有多个composite时,将多个composite合并成一个composite;
List<SCAContribution> contributions = new ArrayList<SCAContribution>(); // 创建局部贡献包集合
// 容器内composite多于一个时
if (composites != null && composites.length > 1) {
// 将所有的composite转换至一个composite
String content = createDeploymentComposite(applicationClassLoader, composites);
// 创建贡献包
for (String location : contributionURLs) {
contributions.add(new SCAContribution(location, location));
}
node =
factory.createSCANode("http://tuscany.apache.org/xmlns/sca/1.0/aggregated", content, contributions
.toArray(new SCAContribution[contributions.size()]));
} else {//只有一个或为null时
for (String location : contributionURLs) {
contributions.add(new SCAContribution(location, location));
}
// 如果只有一个Composite就获取,不然返回null
String composite = (composites != null && composites.length >= 1) ? composites[0] : null;
// 创建NodeImpl
if (!contributions.isEmpty()) {
node =
factory.createSCANode(composite, contributions.toArray(new SCAContribution[contributions.size()]));
} else {
// 默认单个compusite
node = factory.createSCANodeFromClassLoader(composite, applicationClassLoader);
}
}
2.3 强转赋值SCA客户端
client = (SCAClient)node;
2.4 设置端口
setDefaultPort();//设置端口,没有就不设,默认不设置
2.5 启动节点
node.start();//节点启动
2.6 将所有组件添加至组件集合中
getComponents(compositeActivator.getDomainComposite());
3.获取服务
public <B> B getService(Class<B> businessInterface, String serviceName) {
return client.getService(businessInterface, serviceName);
}
源码:
public class DefaultSCADomain extends SCADomain {
private String uri; // 默认是"http://localhost"
private String[] composites; // composites配置文件
// private Composite domainComposite;
// private List<Contribution> contributions;
private Map<String, Component> components; // 组件对象集合
private ComponentManager componentManager;// 组件管理器
// private ClassLoader runtimeClassLoader;
private ClassLoader applicationClassLoader; // 应用ClassLoader
private String domainURI; // 原始domainURI
private List<String> contributionURLs; // 贡献包集合
private CompositeActivator compositeActivator;
private SCANode node;
private SCAClient client;
/**
*
* 创建默认SCA域对象
*
* @param runtimeClassLoader 域的classLoader(没用)
*
* @param applicationClassLoader 应用的classLoader,主要使用此classLoader运行;
*
* @param domainURI 默认是"http://localhost"
*
* @param contributionLocation 贡献包路径,默认是"/"
*
* @param composites 默认测试是只能编写一个composite配置文件,而DefaultSCADomain构造函数是多参的;
*
*/
public DefaultSCADomain(ClassLoader runtimeClassLoader,
ClassLoader applicationClassLoader,
String domainURI,
String contributionLocation,
String... composites) {
this.uri = domainURI;
this.composites = composites;
// this.runtimeClassLoader = runtimeClassLoader;
this.applicationClassLoader = applicationClassLoader;
this.domainURI = domainURI;
this.contributionURLs = new ArrayList<String>();
// 默认没有贡献包,创建;
if (contributionLocation != null && !"/".equals(contributionLocation)) {
this.contributionURLs.add(contributionLocation);
}
this.composites = composites;
// 初始化环境
init();
this.componentManager = new DefaultSCADomainComponentManager(this);
}
/**
* A hack to create an aggregated composite
* @param classLoader
* @param composites
* @return
*/
private String createDeploymentComposite(ClassLoader classLoader, String composites[]) {
//.......
}
public void init() {
// TODO 初始化运行环境
// 创建SCANODE工厂
SCANodeFactory factory = SCANodeFactory.newInstance();
List<SCAContribution> contributions = new ArrayList<SCAContribution>();
// 容器内composite多于一个时
if (composites != null && composites.length > 1) {
// 将所有的composite转换至一个composite
String content = createDeploymentComposite(applicationClassLoader, composites);
// 创建贡献包
for (String location : contributionURLs) {
contributions.add(new SCAContribution(location, location));
}
node =
factory.createSCANode("http://tuscany.apache.org/xmlns/sca/1.0/aggregated", content, contributions
.toArray(new SCAContribution[contributions.size()]));
} else {//只有一个或为null时
for (String location : contributionURLs) {
contributions.add(new SCAContribution(location, location));
}
// 如果只有一个Composite就获取,不然返回null
String composite = (composites != null && composites.length >= 1) ? composites[0] : null;
// 创建NodeImpl
if (!contributions.isEmpty()) {
node =
factory.createSCANode(composite, contributions.toArray(new SCAContribution[contributions.size()]));
} else {
node = factory.createSCANodeFromClassLoader(composite, applicationClassLoader);
}
}
client = (SCAClient)node;
compositeActivator = ((NodeImpl)node).getCompositeActivator();
components = new HashMap<String, Component>();
setDefaultPort();//设置端口,没有就不设,默认不设置
node.start();//节点启动
// 添加Component至Map<String, Component> components
getComponents(compositeActivator.getDomainComposite());
}
private void setDefaultPort() {
//..
}
/**
* 获取服务
*/
public <B> B getService(Class<B> businessInterface, String serviceName) {
return client.getService(businessInterface, serviceName);
}
}
组合构件(composite)
组合构件(composite),是最小的独立部署单元,它是组件的容器,是组件、服务、引用以及内连它们的连线的集合体。
配合看源码 - DefaultSCADomain解析
样例:
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"
xmlns:c="http://sample"
targetNamespace="http://sample"
name="echo">
// targetNamespace - 工作空间名,后期发布绑定用
// name - composite的名字
<component name="echoComponent">
<implementation.java
class="com.simple.echo.EchoImp" />
<service name="Echo">
<binding.ws uri="http://localhost:8080/TrceanyMoudle/echoComponent"></binding.ws>
</service>
<reference name="reture" target="EchoReture"/>
</component>
<component name="EchoReture">
<implementation.java class="com.simple.Client.EchoRetureImp"/>
</component>
</composite>