Virgo and Maven integrated development environment construction (2)

          2. Development and integration.

                  After configuring Maven and Virgo, let's write a demo. The demo scenario is that the page has a search box, enter search criteria, and display matching items. In order to reflect the characteristics of OSGI, our search content is divided into two bundles, picture and MP3, which have a common interface. The bundle dependencies are as follows:

                     The host and web bundles are web packages, and the others are application packages.

                     Speaking of the splitting of the package, or the splitting of the module, I will show off a little here, don't spray! Looking at my package dependency structure, one might ask, isn't OSGI all about modularity? Shouldn't it be a module a package? If I have two modules, user and role, there should be two packages. If you think so then you are wrong, I can only say that you have not understood the service-oriented architecture system proposed by OSGI. The page is just the presentation layer, the page-controller-service-dao, which is the traditional layering, which splits the application vertically by function. In the field of OSGI, another concept is proposed, which is modularization. Modularization requires isolation between bundles and bundles. A bundle is a physical unit that interacts through services. How should the service here be reflected? through the interface. How should the interface be designed? Where should the extension point be placed? It should be considered when designing an OSGI application. In the demo, the page enters keywords to search, the user does not know what results can be found, and the results are controlled on the server side. How does the server control the result? Just leave an extension point. Now you can search for MP3 and pictures. After a period of time, after the business expands, you can search for people and news... So, this is why MP3 and pictures are divided into different bundles for development. Another feature of OSGI is dynamic, plug-in mechanism, plug-and-play, delete or nothing. When the program is running, only MP3 and pictures can be searched in the first minute, the server dynamically starts a realization of news search, and the news can be searched in the next minute. That's the magic of OSGI. It feels cumbersome at first, and it feels complicated. Once you're really familiar with it, use it to its best advantage in the right project.

                   

                    1.host

                             First, let's develop the host. Create a Maven Project in eclipse. The Archetype is selected as quickstart. The host is relatively simple, there is no java code, at most we put jQuery in it. The general practice is that the global resource file is placed in the host for other bundles to call. In principle, bundles are physically isolated.

 
 

                           Not too much content is very simple, the focus is on the packaging rules in the pom and the bundler plugin to be introduced later. And the usefulness of the templat.mf file

                           In OSGI, all are jar packages, even web applications. So to package the host project into a bundle in OSGI, you need to define packaging rules in the pom: 

 

	<build>
		<pluginManagement>
			<plugins>				
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>2.3.2</version>
					<configuration>
						<source>1.6</source>
						<target>1.6</target>
					</configuration>
				</plugin>

				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-resources-plugin</artifactId>
					<version>2.5</version>
					<executions>
						<execution>
							<id>copy-resources</id>
							<phase>prepare-package</phase>
							<goals>
								<goal>copy-resources</goal>
							</goals>
							<configuration>
								<overwrite>true</overwrite>
								<outputDirectory>${project.build.outputDirectory}/WEB-INF/classes</outputDirectory>
							<resources>
								<resource>
									<directory>${project.build.outputDirectory}</directory>
									<includes>
										<include>**/*.class</include>
									</includes>
								</resource>
							</resources>
						</configuration>
				</execution>
		</executions>
      </plugin>

				
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-surefire-plugin</artifactId>
					<version>2.9</version>
				</plugin>
				
			<plugin>
				<groupId>org.eclipse.virgo.bundlor</groupId>
				<artifactId>org.eclipse.virgo.bundlor.maven</artifactId>
				<version>1.1.1.RELEASE</version>
				<executions>
					<execution>
						<id>bundlor</id>
						<goals>
							<goal>bundlor</goal>
						</goals>
						<configuration>
						    <OSGiProfilePath>./virgo.profile</OSGiProfilePath>
						</configuration>
					</execution>
				</executions>
			</plugin>
			
			<plugin>
        		<groupId>org.apache.maven.plugins</groupId>
        		<artifactId>maven-source-plugin</artifactId>
        		<version>2.1.2</version>
        		<executions>
          			<execution>
            			<id>attach-sources</id>
            			<phase>verify</phase>
            			<goals>
              				<goal>jar-no-fork</goal>
            			</goals>
          			</execution>
        		</executions>
      		</plugin>
      		
 			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<includes>
						<include>WEB-INF/**/*</include>
						<include>META-INF/**/*</include>
						<include>resource*/**/*</include>
						<include>**/*.html</include>
						<include>**/*.js</include>
						<include>**/*.css</include>
						<include>**/*image*/**/*</include>
					</includes>
					<archive>
            			<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
          			</archive>
				</configuration>
				<version>2.4</version>
			</plugin>
			</plugins>
		</pluginManagement>
		
  	<plugins>
  			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.eclipse.virgo.bundlor</groupId>
				<artifactId>org.eclipse.virgo.bundlor.maven</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
			</plugin>
			<plugin>
        		<groupId>org.apache.maven.plugins</groupId>
        		<artifactId>maven-source-plugin</artifactId>
      		</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-resources-plugin</artifactId>
			</plugin>
  	</plugins>
	</build>
	

                    This rule can be made into a maven parent project, and other bundles used as web can inherit this parent.

 

                    Then take a look at template.mf:

 

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: search demo
Bundle-SymbolicName: org.phantom.demo.host
Bundle-Version: 1.0.0.SNAPSHOT
Web-ContextPath: /demo
Import-Template: org.eclipse.virgo.*;version="[3.5.0,4)"
Excluded-Exports: resources.*

                    The things to be explained here are Import-Template, Excluded-Exports, Excluded-Import. These are not OSGI native things, they are Virgo specific descriptors. Having said that, I have to introduce the org.eclipse.virgo.bundlor.maven plugin. When this plugin is packaged, it will scan all java classes, spring configuration files, and some other specific files of web.xml. Then combined with the template.mf file, META-INF/MANIFEST.MF is finally generated. If you import other bundles in the java class: import org.apache.ibatis.session.SqlSession; and you don't need to manually maintain the Import-Package in template.mf, bundler will scan it, and when it is generated, it will Write in Import-Package: Import-Package: org.apache.ibatis.session. There is another feature, bundlor will check Import-Template, Excluded-Exports, Excluded-Import, and fill in the scanned dependencies according to the description items. Suppose, you write Import- Template: org.springframework.*;version="[3.5.0,4)" in template.mf, and you use spring things such as DispatcherServlet during development, then in the final generated In MANIFEST.MF, there will be Import-Package: org.springframework.web.servlet;version=3.5.0.

                    We know that in the development of OSGI, the most troublesome and most prone to problems, one is the problem of ClassLoad, and the other is the dependencies between bundles. Therefore, the bundler plugin combined with the template.mf file has helped us a lot. We don't need to manually maintain the dependencies between bundles, and sometimes we don't even need to care, because the bundler plugin will scan and generate.
                    One configuration is Web-ContextPath: /demo . This is the context of our entire application.

                    Finally take a look at web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">

	<display-name>Search Host</display-name>

	<filter>
		<filter-name>host-filter</filter-name>
		<filter-class>org.eclipse.virgo.snaps.core.SnapHostFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>host-filter</filter-name>
		<url-pattern>/*</url-pattern>
		<dispatcher>INCLUDE</dispatcher>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>REQUEST</dispatcher>
	</filter-mapping>

	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

                        这里需要介绍一下SnapHostFilter.这是Virgo对WAB(web application bundle)做的支持.我们在做OSGI-Web开始时,一般有很多模块.比如用户(user),角色(role).那么我们要请求用户或者角色下的资源时,我们的URL就是http://localhost:8080/demo/user/xxx.html或者http://localhost:8080/demo/role/xxx.html。这里的demo就上前面的配置“Web-ContextPath: /demo”,/demo是第一级路径,/user第二级路径是,即我们的"Snap-ContextPath: /search",这个后续的篇章会介绍./demo由web容器去分发,当tomcat接受到请求后,根据第一级路径决定分发到哪个应用。当进到某个应用后,SnapHostFilter会根据第二级路径决定分发到哪个bundle中。这就是SnapHostFilter的作用了。

                   

                   2.api

                       OK,host已经完成,我们来开发api这个包.api中放两个接口,先来看一下结构.


                        SearchBean做为标识接口,没有任何代码.因为我们的接口不知道具体返回的MP3或者图片中包含什么属性.所以这里不定义任何属性.

                        SearchHandler只有简单的一个方法:

package org.phantom.demo.api;

import java.util.List;

public interface SearchHandler {
	List<? extends SearchBean> doSearch(String key);
}

                      然后来看应用类型的bundle应该如何打包.它也有自己的打包规则,而且跟web类的bundle不太一样,因为没有页面文件哪些东西。

	<build>
		<pluginManagement>
			<plugins>				
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>2.3.2</version>
					<configuration>
						<source>1.6</source>
						<target>1.6</target>
					</configuration>
				</plugin>
				
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-surefire-plugin</artifactId>
					<version>2.9</version>
				</plugin>
				
			<plugin>
				<groupId>org.eclipse.virgo.bundlor</groupId>
				<artifactId>org.eclipse.virgo.bundlor.maven</artifactId>
				<version>1.1.1.RELEASE</version>
				<executions>
					<execution>
						<id>bundlor</id>
						<goals>
							<goal>bundlor</goal>
						</goals>
						<configuration>
						    <OSGiProfilePath>./virgo.profile</OSGiProfilePath>
						</configuration>
					</execution>
				</executions>
			</plugin>
			
			<plugin>
        		<groupId>org.apache.maven.plugins</groupId>
        		<artifactId>maven-source-plugin</artifactId>
        		<version>2.1.2</version>
        		<executions>
          			<execution>
            			<id>attach-sources</id>
            			<phase>verify</phase>
            			<goals>
              				<goal>jar-no-fork</goal>
            			</goals>
          			</execution>
        		</executions>
      		</plugin>
      		
 			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<archive>
            			<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
          			</archive>
				</configuration>
				<version>2.4</version>
			</plugin>
			</plugins>
		</pluginManagement>
		
  	<plugins>
  			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.eclipse.virgo.bundlor</groupId>
				<artifactId>org.eclipse.virgo.bundlor.maven</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
			</plugin>
			<plugin>
        		<groupId>org.apache.maven.plugins</groupId>
        		<artifactId>maven-source-plugin</artifactId>
      		</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-resources-plugin</artifactId>
			</plugin>
  	</plugins>
	</build>

                          Compared with the packaging of web-bundle, it is simpler. It can still be made into a parent project, and it is OK for all application class bundles to inherit.

 

                    We know that in the development of OSGI, the most troublesome and most prone to problems, one is the problem of ClassLoad, and the other is the dependencies between bundles. Therefore, the bundler plugin combined with the template.mf file has helped us a lot. We don't need to manually maintain the dependencies between bundles, and sometimes we don't even need to care, because the bundler plugin will scan and generate. One configuration is Web-ContextPath: /demo . This is the context of our entire application.

                    Finally take a look at web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">

	<display-name>Search Host</display-name>

	<filter>
		<filter-name>host-filter</filter-name>
		<filter-class>org.eclipse.virgo.snaps.core.SnapHostFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>host-filter</filter-name>
		<url-pattern>/*</url-pattern>
		<dispatcher>INCLUDE</dispatcher>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>REQUEST</dispatcher>
	</filter-mapping>

	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

                        这里需要介绍一下SnapHostFilter.这是Virgo对WAB(web application bundle)做的支持.我们在做OSGI-Web开始时,一般有很多模块.比如用户(user),角色(role).那么我们要请求用户或者角色下的资源时,我们的URL就是http://localhost:8080/demo/user/xxx.html或者http://localhost:8080/demo/role/xxx.html。这里的demo就上前面的配置“Web-ContextPath: /demo”,/demo是第一级路径,/user第二级路径是,即我们的"Snap-ContextPath: /search",这个后续的篇章会介绍./demo由web容器去分发,当tomcat接受到请求后,根据第一级路径决定分发到哪个应用。当进到某个应用后,SnapHostFilter会根据第二级路径决定分发到哪个bundle中。这就是SnapHostFilter的作用了。

                   

                   2.api

                       OK,host已经完成,我们来开发api这个包.api中放两个接口,先来看一下结构.


                        SearchBean做为标识接口,没有任何代码.因为我们的接口不知道具体返回的MP3或者图片中包含什么属性.所以这里不定义任何属性.

                        SearchHandler只有简单的一个方法:

package org.phantom.demo.api;

import java.util.List;

public interface SearchHandler {
	List<? extends SearchBean> doSearch(String key);
}

                      然后来看应用类型的bundle应该如何打包.它也有自己的打包规则,而且跟web类的bundle不太一样,因为没有页面文件哪些东西。

	<build>
		<pluginManagement>
			<plugins>				
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>2.3.2</version>
					<configuration>
						<source>1.6</source>
						<target>1.6</target>
					</configuration>
				</plugin>
				
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-surefire-plugin</artifactId>
					<version>2.9</version>
				</plugin>
				
			<plugin>
				<groupId>org.eclipse.virgo.bundlor</groupId>
				<artifactId>org.eclipse.virgo.bundlor.maven</artifactId>
				<version>1.1.1.RELEASE</version>
				<executions>
					<execution>
						<id>bundlor</id>
						<goals>
							<goal>bundlor</goal>
						</goals>
						<configuration>
						    <OSGiProfilePath>./virgo.profile</OSGiProfilePath>
						</configuration>
					</execution>
				</executions>
			</plugin>
			
			<plugin>
        		<groupId>org.apache.maven.plugins</groupId>
        		<artifactId>maven-source-plugin</artifactId>
        		<version>2.1.2</version>
        		<executions>
          			<execution>
            			<id>attach-sources</id>
            			<phase>verify</phase>
            			<goals>
              				<goal>jar-no-fork</goal>
            			</goals>
          			</execution>
        		</executions>
      		</plugin>
      		
 			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<archive>
            			<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
          			</archive>
				</configuration>
				<version>2.4</version>
			</plugin>
			</plugins>
		</pluginManagement>
		
  	<plugins>
  			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.eclipse.virgo.bundlor</groupId>
				<artifactId>org.eclipse.virgo.bundlor.maven</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
			</plugin>
			<plugin>
        		<groupId>org.apache.maven.plugins</groupId>
        		<artifactId>maven-source-plugin</artifactId>
      		</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-resources-plugin</artifactId>
			</plugin>
  	</plugins>
	</build>

                          相比较web-bundle的打包要简单一些。仍然可以做成一个parent项目,所有的应用类bundle去继承就OK了。

 

Guess you like

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