在学习tuscany到过程遇到一个疑问(java组件实现是如何解析java类文件中的服务的?如果没有配置服务,默认服务应该是什么?),开始的时候一直无法想清楚,通过阅读源码终于了解了部分解析过程
以tuscany中的Calculator为例说明服务的定义:
1. 如果按照例子本身的代码和配置,我们应该如何获取服务呢?
CalculatorService实现代码
package calculator;
import org.osoa.sca.annotations.Reference;
/**
* An implementation of the Calculator service.
*/
public class CalculatorServiceImpl implements CalculatorService {
private AddService addService;
private SubtractService subtractService;
private MultiplyService multiplyService;
。。。。。。。。。。。。。
配置:
<component name="CalculatorServiceComponent">
<implementation.java class="calculator.CalculatorServiceImpl"/>
<reference name="addService" target="AddServiceComponent" />
<reference name="subtractService" target="SubtractServiceComponent" />
<reference name="multiplyService" target="MultiplyServiceComponent" />
<reference name="divideService" target="DivideServiceComponent" />
</component>
a. 例子中获取服务的方法:
CalculatorService calculatorService =
scaDomain.getService(CalculatorService.class, "CalculatorServiceComponent");
通过上述代码我们就可以获取相应的服务了,我们不仅要问,为什么能够获取相应的服务呢?
根据java组件实现规范说明,如果组件只包含一个服务,那么我们在获取服务的时候可以省略服务的名字。
我的问题是:省略的服务名字是什么?
b. 完整获取服务的方法:
CalculatorService calculatorService1 =scaDomain.getService(CalculatorService.class, "CalculatorServiceComponent/CalculatorServiceImpl");
大家通过比较就可以知道,其实省略的
服务名字是 CalculatorServiceImpl
为什么是这个名字,大家可以参考源码中的
if (services.isEmpty()) {
// class is the interface
addService(type, clazz);
}
2. 自己定义一个服务
自己在实现中添加服务声明
1 @Service(CalculatorService.class)
2 public class CalculatorServiceImpl implements CalculatorService {
3
4 private AddService addService;
5 private SubtractService subtractService;
6 private MultiplyService multiplyService;
7 private DivideService divideService;
。。。。。。
我们可以通过如下方式获取服务:
a. 例子中的方式
CalculatorService calculatorService =
scaDomain.getService(CalculatorService.class, "CalculatorServiceComponent");
b. 完整方式
CalculatorService calculatorService1 =scaDomain.getService(CalculatorService.class, "CalculatorServiceComponent/CalculatorService");
我们通过如下方式就*不能*获取服务了
CalculatorService calculatorService1 =scaDomain.getService(CalculatorService.class, "CalculatorServiceComponent/CalculatorServiceImpl");
原因很简单,实现不会再添加默认服务(
CalculatorServiceImpl)了
源码摘录如下:
1 org.apache.tuscany.sca.implementation.java.introspect.impl.HeuristicPojoProcessor
2
3
4 public <T> void visitEnd(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
5 List<org.apache.tuscany.sca.assembly.Service> services = type.getServices();
6 if (services.isEmpty()) {
7 // heuristically determine the service
8 /**
9 * The following is quoted from Java Specification 1.2.1.3. Introspecting services offered by a Java implementation
10 * In the cases described below, the services offered by a Java implementation class may be determined
11 * through introspection, eliding the need to specify them using @Service. The following algorithm is used
12 * to determine how services are introspected from an implementation class:
13 *
14 * If the interfaces of the SCA services are not specified with the @Service annotation on the
15 * implementation class, it is assumed that all implemented interfaces that have been annotated
16 * as @Remotable are the service interfaces provided by the component. If none of the implemented
17 * interfaces is remotable, then by default the implementation offers a single service whose type
18 * is the implementation class.
19 */
20 Set<Class> interfaces = getAllInterfaces(clazz);
21 for (Class<?> i : interfaces) {
22 if (i.isAnnotationPresent(Remotable.class) || i.isAnnotationPresent(WebService.class)) {
23 addService(type, i);
24 }
25 }
26 if (services.isEmpty()) {
27 // class is the interface
28 addService(type, clazz);
29 }
30 }
31 Set<Method> methods = getAllUniquePublicProtectedMethods(clazz, false);
32 if (!type.getReferenceMembers().isEmpty() || !type.getPropertyMembers().isEmpty()) {
33 // references and properties have been explicitly defined
34 // if (type.getServices().isEmpty()) {
35 // calculateServiceInterface(clazz, type, methods);
36 // if (type.getServices().isEmpty()) {
37 // throw new ServiceTypeNotFoundException(clazz.getName());
38 // }
39 // }
40 evaluateConstructor(type, clazz);
41 return;
42 }
43 calcPropRefs(methods, services, type, clazz);
44 evaluateConstructor(type, clazz);
45 }
46