在學習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