首页产品库评测行情新闻|手机数码笔记本台式机DIY硬件数字家庭数码相机办公外设|软件下载游戏开发|社区

更多

数码相机
MP4
LCD
机箱
音箱

软件资讯设计 工具 系统 开发 安全 办公 陶吧 IT教育 Vista频道 | 下载中心酷我音乐盒 腾讯QQ
天极网 > 开发频道>Tucany SCA软件架构设计理念分析之二

Tucany SCA软件架构设计理念分析之二

2007-12-04 10:32作者:lijj出处:论坛整理责任编辑:方舟

  4. 分专题来讨论SCA调用知识点

  (1) Inject(IOC注射)

  下面再涉及一个知识点Inject,如图所示,黄色的部分,即在创建实例时,要注射进取的东西,分为两类,MethodInject,和FieldInject,就是我们或者在源代码中annotation,或者在配置文件中配置的(Injects列表具体如何加入到系统中,将在Assembly中详细讲解)

<reference name="addService" target="AddServiceComponent" />
<reference name="subtractService" target="SubtractServiceComponent" />
<reference name="multiplyService" target="MultiplyServiceComponent" />
<reference name="divideService" target="DivideServiceComponent" />
<component name="AddServiceComponent">
<implementation.java class="calculator.AddServiceImpl"/>
</component>
<component name="SubtractServiceComponent">
<implementation.java class="calculator.SubtractServiceImpl"/>
</component>
<component name="MultiplyServiceComponent">
<implementation.java class="calculator.MultiplyServiceImpl"/>
</component>
<component name="DivideServiceComponent">
<implementation.java class="calculator.DivideServiceImpl"/>
</component>

  都要求在这个实例创建时,初始化进去,即动态注射到我们的实例中来,其中象“AddServiceComponent”这样的类,同样也是通过IOC的方式创建出来。

org.apache.tuscany.sca.implementation.java.context.ReflectiveInstanceFactory<T>

public InstanceWrapper<T> newInstance() {
 T instance;
 try {
  if (ctrArgs != null) {
   Object[] args = new Object[ctrArgs.length];
   for (int i = 0; i < args.length; i++) {
    args[i] = ctrArgs[i].getInstance();
   }
   instance = ctr.newInstance(args);
  } else {
   instance = ctr.newInstance();
  }
 } catch (InstantiationException e) {
  String name = ctr.getDeclaringClass().getName();
  throw new AssertionError("Class is not instantiable [" + name + "]");
 } catch (IllegalAccessException e) {
  String name = ctr.getName();
  throw new AssertionError("Constructor is not accessible [" + name + "]");
 } catch (InvocationTargetException e) {
  String name = ctr.getName();
  throw new ObjectCreationException("Exception thrown by constructor: " + name, e);
}

if (injectors != null) {
 for (Injector<T> injector : injectors) {
  //FIXME Injectors should never be null
  if (injector != null)
   injector.inject(instance);
 }
}

  (2) 同步调用和异步调用

  当使用异步调用时,必须设置CallbackEndpoint,这样当系统获取请求后,在后台处理,至于处理的结果则需要调用CallbackEndpointer才能获得,同步调用时设置把处理结果直接放在调用的Target中,其实就是谁调用,把结果返回给谁。

org.apache.tuscany.sca.core.invocation.JDKInvocationHandler

if (wire.getSource() != null && wire.getSource().getCallbackEndpoint() != null) {
 if (callbackObject != null) {
  if (callbackObject instanceof ServiceReference) {
    msg.setFrom(((CallableReferenceImpl)callbackObject).getRuntimeWire().getTarget());
  } else {
   if (contract != null) {
    if (!contract.isConversational()) {
     throw new NoRegisteredCallbackException(
"Callback object for stateless callback is not a ServiceReference");
    } else {
     //FIXME: add callback object to scope container
     msg.setFrom(wire.getSource().getCallbackEndpoint());
    }
   }
  }
 } else {
  //FIXME: check that the source component implements the callback interface
  msg.setFrom(wire.getSource().getCallbackEndpoint());
 }
}

if (endpoint != null) {
 msg.setTo(endpoint);
} else {
 msg.setTo(wire.getTarget());
}

  (3) 调用的状态的维护

  其调用的状态范围分为:STATELESS,REQUEST,SESSION,CONVERSATION,COMPOSITE,SYSTEM,UNDEFINED。从字面意思上很容易理解“STATELESS,REQUEST,SESSION”,这和我们一起接触到的web应用非常的类似,都是基于同一个jvm之上的概念,“CONVERSATION”是基于对话级别的,类似于单jvm中的Application,“COMPOSITE”是composite级别的,因为Composite可以跨进程(jvm),可以跨机器部署,所以“COMPOSITE”是更高级别的状态共享。“SYSTEM”是基于domain级别的状态控制。

org.apache.tuscany.sca.core.scope.scope

public static final Scope STATELESS = new Scope("STATELESS");
public static final Scope REQUEST = new Scope("REQUEST");
public static final Scope SESSION = new Scope("SESSION");
public static final Scope CONVERSATION = new Scope("CONVERSATION");
public static final Scope COMPOSITE = new Scope("COMPOSITE");
public static final Scope SYSTEM = new Scope("SYSTEM");
public static final Scope UNDEFINED = new Scope("UNDEFINED");

  其中CONVERSATION控制更进一步,设置了CONVERSATION会话顺序ConversationSequence 的Enumeration

public enum ConversationSequence {
 CONVERSATION_NONE, CONVERSATION_START, CONVERSATION_CONTINUE, CONVERSATION_END
}

  在org.apache.tuscany.sca.core.invocation.JDKInvocationHandler中有根据会话顺序的状态进行控制的逻辑,在调用的参数封装类Message中设置会话顺序状态。

Interface contract = operation.getInterface();

if (contract != null && contract.isConversational()) {
 ConversationSequence sequence = operation.getConversationSequence();
 if (sequence == ConversationSequence.CONVERSATION_END) {
  msg.setConversationSequence(ConversationSequence.CONVERSATION_END);
  conversationStarted = false;
  if (conversation != null) {
   conversation.setConversationID(null);
  }
 } else if (sequence == ConversationSequence.CONVERSATION_CONTINUE) {
  if (conversationStarted) {
   msg.setConversationSequence(ConversationSequence.CONVERSATION_CONTINUE);
  } else {
   conversationStarted = true;
   msg.setConversationSequence(ConversationSequence.CONVERSATION_START);
  }
 }
}

  同时org.apache.tuscany.sca.implementation.java.invocation.JavaImplementationInvoker的代码中根据从message中获取的会话顺序状态,来获取ScopeContainer中保存的InstanceWrapper的实例封装类,其中ScopeContainer中也有个HashMap来保存相应的实例封装类。Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

protected Map<KEY, InstanceWrapper<?>> wrappers = new ConcurrentHashMap<KEY, InstanceWrapper<?>>();

protected volatile int lifecycleState = UNINITIALIZED;
private InstanceWrapper getInstance(ConversationSequence sequence, Object contextId)
throws TargetResolutionException, InvalidConversationSequenceException {

 if (sequence == null) {
  return scopeContainer.getWrapper(contextId);
 } else {
  switch (sequence) {
   case CONVERSATION_START:
    return scopeContainer.getWrapper(contextId);
   case CONVERSATION_CONTINUE:
   case CONVERSATION_END:
    return scopeContainer.getAssociatedWrapper(contextId);
   default:
    throw new InvalidConversationSequenceException("Unknown sequence type: " + String.valueOf(sequence));
  }
 }
}

  (4) 在传递过程Message的线程副本的应用

  如在org.apache.tuscany.sca.core.invocation.ThreadMessageContext

  相当于内存共享区,其中key为 Thread,value值为message,即要保存的内容

private static final ThreadLocal<Message> CONTEXT = new ThreadLocal<Message>() {
 @Override
 protected synchronized Message initialValue() {
  return new MessageImpl();
 }
};

public static Message setMessageContext(Message context) {
 Message old = CONTEXT.get();
 CONTEXT.set(context);
 return old;
}

public static Message getMessageContext() {
 return CONTEXT.get();
}

  ThreadLocal线程局部变量, 就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。类似的应用还出现在spring,hibernate中。

  5. 结束语

  本文首先介绍了动态代理Poxy及Invocation方面的基础知识,分析了Tuscany SCA在运用这一原理来实现IOC功能,并深入介绍了Component的设计理念和EJB的异曲同工之妙,底层实现却采用了类似轻量级框架Spring的实现原理,以后还有Assembly,Contribute和Binding的具体设计思想,最后介绍Tuscany整体架构设计思想,敬请关注。共享是我的准则,共同提高是我的目标。

  努力,在于我热爱我的事业,与中国的软件一起走向成熟,走向世界。
共3页。 上一页123
进入 最权威的Windows 7论坛 查看网友讨论

软件频道最新更新

热点推荐

IT嘉年华

编辑推荐

软件下载

热门
推荐

网友关注

软件
资料
游戏

装机推荐

文章排行

本周
本月
最新更新
天极服务|关于我们|About us|网站律师|RSS订阅|友情合作|加入我们|天极动态|网站地图|意见反馈|MSN/QQ上看天极
Copyright (C) 1999-2012 Yesky.com, All Rights Reserved 版权所有 天极网络