Osgi service: Suitable for SOA Architecture

Source: Internet
Author: User

This article is
Good, osgi
The fourth part of the series. The following describes the osgi service. Readers who are not familiar with osgi can first read what osgi is.
Article.

Osgi Service

As mentioned above, the osgi architecture is very suitable for implementing service-oriented applications (SOA ). It allows bundles to export services, while other bundles can
Bundles any information to consume these exported services. Because osgi has the ability to hide real service implementation classes, it provides a good combination of classes and interfaces for service-oriented applications.

In the osgi framework, the source bundle registers a pojo object in the osgi container. This object does not have to implement any interfaces or inherit any superclasses, but can be registered on one or more interfaces.
And provide external services. The target bundle can request a service registered under an interface from the osgi container. Once it discovers the service, the target bundle binds the service to this interface,
And can call methods in this interface. The following is an example to better understand osgi-related concepts.

5.1. Export Service

In this section, we will update helloservice bundle so that it can export the objects of the helloserviceimpl class as services. The specific steps are as follows:

1) Modify com. javaworld. sample. helloservice
The manifest. MF file in the bundle to import the org. osgi. Framework Package );

2)
Create a Java class com. javaworld. sample. impl. helloserviceactivator. java. The source code is shown in listing 7;

Source code list 7. helloserviceactivator. Java

Public class helloserviceactivator implements bundleactivator {
Serviceregistrationhelloserviceregistration;
Public void start (bundlecontext context) throws exception {
Helloservice = newhelloserviceimpl ();
Helloserviceregistration = context. registerservice (helloservice. Class. getname (), helloservice, null );
}
Public void stop (bundlecontext context) throws exception {
Helloserviceregistration. unregister ();
}
}

Note that in the source bundle, we should use the bundlecontext. registerservice () method to export the service. This method has three parameters:

A)
The first parameter of this method is the name of the service interface you want to register. If you want to register your service to multiple interfaces, you need to create a new string array to store these interface names, and then use this array
The first parameter is passed to the registerservice () method. In the sample code, we want to export our service to the helloserver interface;

B) The second parameter is the actual Java object of the service to be registered. In the sample code, we export the helloserviceimpl Class Object and use it as a service;

C)
The third parameter is the service attribute, which is a dictionary object. If multiple bundle export services have the same interface name, the target bundle can use these attributes
Bundle to filter and find the services it is interested in.

3)
Finally, modify the manifest. MF file in helloservicebundle and change the value of the bundle-activator attribute header
Com. javaworld. sample. Service. impl. helloserviceactivator.

Now helloservice
Bundle to export the helloserviceimpl object. When the osgi container starts helloservicebundle, it gives control
Helloserviceactivator. Java class, helloserviceactivator registers helloserviceimpl object as a server
Service. Next, we start to create the consumer of the service.

5.2. Import Service

In this section, we will modify the developed helloworld
Bundle to make it a consumer of the helloservice service. You must modify the activator. Java generation in helloworldbundle.
The modified code is shown in source code list 8:

Source code list 8. activator. Java in helloworld bundle

Packagecom. javaworld. sample. helloworld;
 
Importorg. osgi. Framework. bundleactivator;
Importorg. osgi. Framework. bundlecontext;
Importorg. osgi. Framework. servicereference;
Importcom. javaworld. sample. Service. helloservice;
 
Publicclass activator implements bundleactivator {
Servicereference helloservicereference;
Public void start (bundlecontext context) throws exception {
System. Out. println ("helloworld !! ");
Helloservicereference = context. getservicereference (helloservice. Class. getname ());
Helloservice = (helloservice) Context. getservice (helloservicereference );
System. Out. println (helloservice. sayhello ());
}
Public void stop (bundlecontext context) throws exception {
System. Out. println ("Goodbye World !! ");
Context. ungetservice (helloservicereference );
}
}

In the code above, the bundlecontext. getservicereference () method will return the service registered under the helloservice Interface
Returns a servicereference object. If multiple helloservice services exist, this method returns the most ranked Service (the ranking of the service is through
Constants. service_ranking attribute ). Once you obtain the servicereference object, you can call its
Bundlecontext. getservice () method to obtain real service objects.

You can run the preceding example application by referring to the method for running bundle. Click "Run à run ..." Menu, and make sure that helloworld and helloservice
Two bundle are selected. When you start helloservicebundle, you will see
"Insidehelloserviceimple. sayhello ()", the message is sent by the helloserviceimpl. sayhello () method
Printed.

5.3. Create a Service Factory

In the previous section, we learned how to use the osgi framework to create a Java object, register it as a service, and then let other bundle consume the service. If you have a look
Helloserviceactivator. Start () method. You will notice that we have created a helloserviceimpl class pair in the START () method.
And then register it to the helloservice interface name. In this way, when any other bundle requests the helloservice service, the osgi container will return the same
An object.

In most cases, this implementation method is fine. However, for example, we need to return different helloserviceimpl objects for each bundle consumer.
The service to be provided by your service object is to open a database connection, but it is not to open it immediately, but to open the database connection only when necessary.

In both cases, we can solve this problem by creating a class to implement the servicefactory interface and registering the class object as a service, but not registering the actual service object. Once
After you complete this step, when other bundle requests the service, your servicefactory implementation class will take over the request, and servicefactory will
Bundle creates a service object and delays the creation time of the real service until someone actually needs the service.

Next we will use servicefactory to update
Com. javaworld. sample. helloservicebundle. The procedure is as follows:

1) create a factory class helloservicefactory. java. The source code is shown in listing 9.

Source code list 9. helloservicefactory. Java

Public class helloservicefactory implements servicefactory {
Private int usagecounter = 0;
Public object getservice (bundle, serviceregistration Registration ){
System. Out. println ("create objectof helloservice for" + bundle. getsymbolicname ());
Usagecounter ++;
System. Out. println ("number ofbundles using service" + usagecounter );
Helloservice = newhelloserviceimpl ();
Return helloservice;
}
Public void ungetservice (bundle, serviceregistration registration, Object Service ){
System. Out. println ("Release objectof helloservice for" + bundle. getsymbolicname ());
Usagecounter --;
System. Out. println ("number ofbundles using service" + usagecounter );
}
}

From the code above, we can see that the servicefactory interface defines two methods:

A)
Getservice () method: When a bundle uses bundlecontext. getservice (servicereference) for the first time
The osgi Framework calls this method when requesting a service object. In source code listing 9, we use this method to create a new bundle and return a different
Helloserviceimpl object. If this object is not null, The osgi framework caches this object. If the same bundle is called again
Bundlecontext. getservice (servicereference) method. osgi returns the same service object.

B)
Ungetservice () method: When a bundle releases a service, the osgi container can call this method to destroy the service object. In source code listing 9, we use
Usagecounter variable is used to track the number of services used and print the number of clients of the service.

2) Modify helloservice
The START () method of helloserviceactivator. Java in the bundle, so that it registers to the servicefactory interface, instead
Register with the helloservice interface. Detailed code is shown in listing 10:

Source code list 10. helloserviceactivator. Java in the modified helloservicebundle

Package com. javaworld. sample. Service. impl;
Importorg. osgi. Framework. bundleactivator;
Importorg. osgi. Framework. bundlecontext;
Importorg. osgi. Framework. serviceregistration;
 
Importcom. javaworld. sample. helloservice. helloservicefactory;
Importcom. javaworld. sample. Service. helloservice;
 
Publicclass helloserviceactivator implements bundleactivator {
Serviceregistrationhelloserviceregistration;
Public void start (bundlecontext context) throws exception {
Helloservicefactory = new helloservicefactory ();
Helloserviceregistration = context. registerservice (helloservice. Class. getname (), helloservicefactory, null );
}
Public void stop (bundlecontext context) throws exception {
Helloserviceregistration. unregister ();
}
}

Now you can test the sample code. You will notice that when helloworld
When the bundle is started, the service counter changes to 1; When helloworldbundle is stopped, the number of service counters changes to 0.

5.4. Tracking Service

In the osgi service section, you learned how to use the service's interface name to search for a service. But if multiple bundle uses the same interface name to register the service, what will happen? This
The osgi container returns the Service with the highest ranking, that is, the Service with the highest service_ranking attribute value at registration. If multiple services have the same ranking value, osgi
The container returns the service with the smallest PID value.

However, if your service consumer needs to know when and when the service object under a certain interface is registered, you should use the servicetracker class. Next, let's take a look
How to use the service tracker to modify our sample code is as follows.

1) modify the manifest. MF file of helloworldbundle to import the org. osgi. util. Tracker package;

2) create a class helloservicetracker. java. For the source code, see listing 11.

Source code list 11. helloservicetracker. Java

Public class helloservicetracker extends servicetracker {
Public helloservicetracker (bundlecontext context ){
Super (context, helloservice. Class. getname (), null );
}
Public object addingservice (servicereference reference ){
System. Out. println ("Inside helloservicetracker. addingservice" + reference. getbundle ());
Return super. addingservice (reference );
}
Public void removedservice (servicereference reference, Object Service ){
System. Out. println ("Inside helloservicetracker. removedservice" + reference. getbundle ());
Super. removedservice (reference, Service );
}
}

In the preceding helloserivcetracker class constructor, you can see that we pass the helloservice interface name to its parent class, which is equivalent
Helloservicetracker should track all services registered to the helloservice interface, and helloservicetracker inherits from
The servicetracker class implements the following two methods:

A) addingservice () method: This method will be called when bundle registers a service using the interface name;

B) removedservice () method: This method is called when bundle unregisters a service under an interface.

3)
Use the helloservicetracker class to update our activator. Java class so that it can manage services rather than directly searching for them. For the source code, see the list.
12.

Source code list 12. activator. Java using helloservicetracker

Public class activator implements bundleactivator {
Helloservicetracker;
Public void start (bundlecontext context) throws exception {
System. Out. println ("Hello world !! ");
Helloservicetracker = new helloservicetracker (context );
Helloservicetracker. open ();
Helloservice = (helloservice) helloservicetracker. getservice ();
System. Out. println (helloservice. sayhello ());
}

Public void stop (bundlecontext context) throws exception {
System. Out. println ("Goodbye World !! ");
Helloservicetracker. Close ();
}
}

We can see that in the initial start () method, we first create a helloservicetracker object and then require this object to be tracked.
The Service under the helloservice interface. In this case, we can call the getservice () method to obtain the helloservice object.

If you test the sample code above, you will notice that when you start or stop helloserivcebundle, The osgi container will call
The addingservice () method or removedservice () method of the helloservicetracker object.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.