在學(xué)習(xí)tuscany到過(guò)程遇到一個(gè)疑問(wèn)(java組件實(shí)現(xiàn)是如何解析java類(lèi)文件中的服務(wù)的?如果沒(méi)有配置服務(wù),默認(rèn)服務(wù)應(yīng)該是什么?),開(kāi)始的時(shí)候一直無(wú)法想清楚,通過(guò)閱讀源碼終于了解了部分解析過(guò)程
以tuscany中的Calculator為例說(shuō)明服務(wù)的定義:
1. 如果按照例子本身的代碼和配置,我們應(yīng)該如何獲取服務(wù)呢?
CalculatorService實(shí)現(xiàn)代碼
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. 例子中獲取服務(wù)的方法:
CalculatorService calculatorService =
scaDomain.getService(CalculatorService.class, "CalculatorServiceComponent");
通過(guò)上述代碼我們就可以獲取相應(yīng)的服務(wù)了,我們不僅要問(wèn),為什么能夠獲取相應(yīng)的服務(wù)呢?
根據(jù)java組件實(shí)現(xiàn)規(guī)范說(shuō)明,如果組件只包含一個(gè)服務(wù),那么我們?cè)讷@取服務(wù)的時(shí)候可以省略服務(wù)的名字。
我的問(wèn)題是:省略的服務(wù)名字是什么?
b. 完整獲取服務(wù)的方法:
CalculatorService calculatorService1 =scaDomain.getService(CalculatorService.class, "CalculatorServiceComponent/CalculatorServiceImpl");
大家通過(guò)比較就可以知道,其實(shí)省略的
服務(wù)名字是 CalculatorServiceImpl
為什么是這個(gè)名字,大家可以參考源碼中的
if (services.isEmpty()) {
// class is the interface
addService(type, clazz);
}
2. 自己定義一個(gè)服務(wù)
自己在實(shí)現(xiàn)中添加服務(wù)聲明
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;
。。。。。。
我們可以通過(guò)如下方式獲取服務(wù):
a. 例子中的方式
CalculatorService calculatorService =
scaDomain.getService(CalculatorService.class, "CalculatorServiceComponent");
b. 完整方式
CalculatorService calculatorService1 =scaDomain.getService(CalculatorService.class, "CalculatorServiceComponent/CalculatorService");
我們通過(guò)如下方式就*不能*獲取服務(wù)了
CalculatorService calculatorService1 =scaDomain.getService(CalculatorService.class, "CalculatorServiceComponent/CalculatorServiceImpl");
原因很簡(jiǎn)單,實(shí)現(xiàn)不會(huì)再添加默認(rèn)服務(wù)(
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