The osgi combat project (osmp) plays with osgi's service release and reference step by step (4)

 

Today I mainly talk about service registration and service reference in the osgi environment.

 

In fact, osgi is just a series of Java dynamic and modular specifications. Different specifications have been formulated according to different manufacturers. For example, Felix and Equinox are the implementation of the standard specifications given by the Apache and Eclipse open source communities respectively! The charm of osgi also lies in its dynamism and modularity. I personally think that the easiest way to achieve dynamism is to dynamically load it through classload. I understand it personally, osgi just abstracts the concept of a bundle component on the basis of traditional development, each bundle component has its own life cycle, and the dynamic implementation of the bundle is based on the bundle classloader. I don't want to talk too much about theoretical things. You can take a look at the basic aspects of osgi, such as bundle life cycle, bundle classloader and so on. And the registration of services, the reference of services, etc. are precisely the best interpretation of the bundle life cycle!

 

Let's talk about service registration in the osgi environment first. In fact, this part of the content has already been said a little in the second lecture. This time we will explain the traditional osgi service registration and the way to use the framework to register.

 

 When a bundle is deployed into an osgi container, there are several most important stages, which can also be called the bundle's life cycle, mainly including  INSTALLED (after calling BundleContext.installBundle(), a bundle in the INSTALLED state will be created), RESOLVED (if its All dependent bundles exist, that is, the resolution is successful, go to RESOLVED state), STARTING (when BundleActivator.start() is executed, it is in STARTING state), ACTIVE (when BundleActivator.start() is executed successfully, go to ACTIVE state), STOPPING (when starting to execute BundleActivator.stop(), it is in STOPPING state), UNINSTALLED (bundles in INSTALLED state can be uninstalled and go to UNINSTALLED state).

It can be seen that the entire life cycle of a bundle is inseparable from the two classes BundleActivator and BundleContext .

 

BundleContext : Bundle context, the main function is to interact with the OSGI container, including service registration, listener registration, access to all published services under osgi, service references and other functions. I suggest that you take a good look at this class.

BundleActivator : BundleActivator is an interface provided by osgi to obtain BundleContext, and also provides processing methods for bundle start and stop.

 

Knowing these two classes, we can implement BundleActivator  to register services to the osgi container through BundleContext when the bundle starts for other bundles to call .


Implement a custom BundleActivator :

 

public class HelloServiceActivator implements BundleActivator {
	ServiceRegistration serviceRegistration;
	@Override
	public void start(BundleContext context) throws Exception {
		HelloService helloService = new HelloServiceImpl();
		serviceRegistration = context.registerService(HelloService.class.getName(), helloService, null);
	}

	@Override
	public void stop(BundleContext context) throws Exception {
		serviceRegistration.unregister();
	}

}

 

When the bundle starts, we instantiate a service class by implementing the start method in the BundleActivator and register it in the osgi container through the registerService of the BundleContext, passing in the service name, service instance, and service alias (which can be understood as this tag) , log out to this service through the stop method.

 

After completing this step, we also define Bundle-Activator as our own Activator in MANIFEST.MF (Bundle metadata description file, which defines the jar package that this Bundle depends on, and the basic metadata such as imported and exported packages).

Bundle-Activator:com.osmp.demo.HelloServiceActivator

 

 In this way, when we deploy this bundle to the osgi container, when the bundle starts, the HelloService will be registered in the osgi container for other bundle services to call. Let's briefly talk about the reference to the bundle service. Basically the same as publishing, the bundle context is obtained through the start method at startup, the ServiceReference  service reference is obtained through the BundleContext, and then the service reference we need is obtained through this class. The code is as follows:

 

public class Activator implements BundleActivator {
ServiceReference helloServiceReference;
	public void start(BundleContext context) throws Exception {
		System.out.println("Hello World!!");
		helloServiceReference=context.getServiceReference(HelloService.class.getName());
		HelloService 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);
	}
}

 

 When I wrote more than half of the above part, I wanted to find two examples, but I found that http://longdick.iteye.com/blog/457310 This article is very good. You can read it, and I will not explain it specifically. .

 

I will talk about how to implement service registration, service discovery and service routing in osmp.

 

We publish the service in osmp through spring-dm, the code is very simple,

 The spring-osgi schema is introduced into the spring configuration file, and the service is published to the osgi container through the <osgi:service> tag. The configuration file is as follows:

 

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:osgi="http://www.springframework.org/schema/osgi"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
		http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd">

	<context:component-scan base-package="com.osmp.demo.service">
	</context:component-scan>
	
	
	<bean id="jdbcDao" class="com.osmp.jdbc.support.JdbcDao"></bean>
	
	<bean id="osmp.demo.service" class="com.osmp.demo.service.TestServiceImpl" />
	<osgi:service interface="com.osmp.intf.define.service.BaseDataService"
		ref="osmp.demo.service">
		<osgi:service-properties>
			<entry key="name" value="osmp-demo" />
			<entry key="mark" value="测试DEMO" />
		</osgi:service-properties>
	</osgi:service>

</beans>

 

Dependencies in pom.xml

 

<dependency>
            <groupId>org.springframework.osgi</groupId>
            <artifactId>spring-osgi-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
 </dependency>

 

pom.xml packages the project as a bundle, you need to use the maven-bundle-plugin plugin:

 

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<extensions>true</extensions>
				<configuration>
					<instructions>
						<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
						<Export-Package></Export-Package>
						<Import-Package>
							org.springframework.aop,
							org.springframework.aop.framework,
							org.springframework.cglib,
							org.springframework.cglib.proxy,
							org.springframework.cglib.core,
							org.springframework.cglib.reflect,
							org.aopalliance.aop,
							org.aopalliance.intercept,
							*;resolution:=optional
						</Import-Package>
					</instructions>
				</configuration>
			</plugin>
		</plugins>
	</build>

 

 

 PS:

1、配置文件引入spring-osgi  xmlns:osgi="http://www.springframework.org/schema/osgi" http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd

2. The osgi:service-properties tag corresponds to the third parameter of the context.registerService() method mentioned above. My understanding is to tag the service in the form of a k/v key-value pair.

3. When maven-bundle-plugin is bundled, the servicemix I use here as an osgi container has integrated spring. At this time, it is necessary to introduce the spring package display . What is more pitted here is that I originally thought that through *;resolution:=optional, the packages that need to be depended can be automatically imported, but I have tried many times and found that only the imported packages displayed in the code will be automatically imported. , such as the dependent packages in the configuration file will not be imported automatically, and can only be imported level by level.

4. The spring-dm service reference is not described in detail here through <osgi:reference>.

 

The above example can view the osmp-demo source code! ! ! !

Relatively speaking, the way to publish services through spring-dm is a big step forward compared to the way through BundleContext above. In addition, you can also publish services through blueprint, and you are interested in Baidu.  

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326837631&siteId=291194637