OSGI和Spring动态模块–简单的Hello World

在此姿势中,我们将采用使用OSGi进行的第一个实现,并使用Spring Dynamic Modules改进应用程序。

Spring动态模块(Spring Dm)使基于OSGi的应用程序的开发更加容易。 这样,服务的部署就容易得多。 您可以像其他任何Spring bean一样注入服务。

因此,让我们从Spring dm开始。

首先,您需要下载Spring Dm Distribution 。 在本文中,我使用了具有依赖关系的发行版,而我将仅使用以下库:

com.springsource.net.sf.cglib-2.1.3.jar
com.springsource.org.aopalliance-1.0.0.jar
log4j.osgi-1.2.15-SNAPSHOT.jar
com.springsource.slf4j.api-1.5.0.jar
com.springsource.slf4j.log4j-1.5.0.jar
com.springsource.slf4j.org.apache.commons.logging-1.5.0.jar
org.springframework.aop-2.5.6.SEC01.jar
org.springframework.beans-2.5.6.SEC01.jar
org.springframework.context-2.5.6.SEC01.jar
org.springframework.core-2.5.6.SEC01.jar
spring-osgi-core-1.2.1.jar
spring-osgi-extender-1.2.1.jar
spring-osgi-io-1.2.1.jar

当然,您可以将Spring 2.5.6库替换为Spring 3.0库。 但是对于本文而言,Spring 2.5.6就足够了。

因此,从服务捆绑开始。 回想一下,该捆绑软件导出了一项服务:

package com.bw.osgi.provider.able;public interface HelloWorldService {void hello();
}
package com.bw.osgi.provider.impl;import com.bw.osgi.provider.able.HelloWorldService;public class HelloWorldServiceImpl implements HelloWorldService {@Overridepublic void hello(){System.out.println("Hello World !");}
}

这里没有要做的任何更改。 现在,我们可以看到激活器:

package com.bw.osgi.provider;import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;import com.bw.osgi.provider.able.HelloWorldService;
import com.bw.osgi.provider.impl.HelloWorldServiceImpl;public class ProviderActivator implements BundleActivator {private ServiceRegistration registration;@Overridepublic void start(BundleContext bundleContext) throws Exception {registration = bundleContext.registerService(HelloWorldService.class.getName(),new HelloWorldServiceImpl(),null);}@Overridepublic void stop(BundleContext bundleContext) throws Exception {registration.unregister();}
}

因此,在这里,我们将简单化。 让我们删除这个类,它对于Spring Dm不再有用。

我们将让Spring Dm为我们导出捆绑包。 我们将为此捆绑包创建一个Spring上下文。 我们只需要在文件夹META-INF / spring中创建一个文件provider-context.xml即可。 这是XML文件中的简单上下文,但是我们使用新的名称空间注册服务“ http://www.springframework.org/schema/osgi ”。 因此,让我们开始:

<?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:osgi="http://www.springframework.org/schema/osgi"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/osgihttp://www.springframework.org/schema/osgi/spring-osgi.xsd"><bean id="helloWorldService" class="com.bw.osgi.provider.impl.HelloWorldServiceImpl"/><osgi:service ref="helloWorldService" interface="com.bw.osgi.provider.able.HelloWorldService"/>
</beans>

OSGi特有的唯一内容是osgi:service声明。 此行表明我们使用接口HelloWorldService作为服务名称将helloWorldService注册为OSGi服务。

如果将上下文文件放在META-INF / spring文件夹中 ,Spring Extender将自动检测到它,并创建一个应用程序上下文。

现在,我们可以转到消费者捆绑包。 在第一阶段,我们创建了该消费者:

package com.bw.osgi.consumer;import javax.swing.Timer;import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;import com.bw.osgi.provider.able.HelloWorldService;public class HelloWorldConsumer implements ActionListener {private final HelloWorldService service;private final Timer timer;public HelloWorldConsumer(HelloWorldService service) {super();this.service = service;timer = new Timer(1000, this);}public void startTimer(){timer.start();}public void stopTimer() {timer.stop();}@Overridepublic void actionPerformed(ActionEvent e) {service.hello();}
}

目前,这里没有任何更改。 可以使用@Resource注释代替构造函数的注入,但这在Spring 2.5.6和Spring Dm中不起作用(但在Spring 3.0中很好用)。

现在激活器:

package com.bw.osgi.consumer;import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;import com.bw.osgi.provider.able.HelloWorldService;public class HelloWorldActivator implements BundleActivator {private HelloWorldConsumer consumer;@Overridepublic void start(BundleContext bundleContext) throws Exception {ServiceReference reference = bundleContext.getServiceReference(HelloWorldService.class.getName());consumer = new HelloWorldConsumer((HelloWorldService) bundleContext.getService(reference));consumer.startTimer();}@Overridepublic void stop(BundleContext bundleContext) throws Exception {consumer.stopTimer();}
}

不再需要注射。 我们可以在这里保持计时器的启动,但是再一次,我们可以使用框架的功能来启动和停止计时器。 因此,让我们删除激活器并创建一个应用程序上下文以创建使用者并自动启动它,并将其放入META-INF / spring文件夹中

<?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:osgi="http://www.springframework.org/schema/osgi"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/osgihttp://www.springframework.org/schema/osgi/spring-osgi.xsd"><bean id="consumer" class="com.bw.osgi.consumer.HelloWorldConsumer" init-method="startTimer" destroy-method="stopTimer"lazy-init="false" ><constructor-arg ref="eventService"/></bean><osgi:reference id="eventService" interface="com.bw.osgi.provider.able.HelloWorldService"/>
</beans>

我们使用了init-method和destroy-method属性来开始和停止框架的时间,并使用构造函数arg注入对服务的引用。 使用osgi:reference字段并使用接口作为服务的键来获取对该服务的引用。

这就是我们与该捆绑包有关的全部。 比第一个版本简单得多吗? 除了简化之外,您还可以看到源不依赖于OSGi或Spring Framework,这是纯Java语言,这是一个很大的优势。

Maven POM与第一阶段的相同,只是我们可以减少对osgi的依赖。

提供者:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>OSGiDmHelloWorldProvider</groupId><artifactId>OSGiDmHelloWorldProvider</artifactId><version>1.0</version><packaging>bundle</packaging><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.0.2</version><configuration><source>1.6</source><target>1.6</target></configuration></plugin><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><extensions>true</extensions><configuration><instructions><Bundle-SymbolicName>OSGiDmHelloWorldProvider</Bundle-SymbolicName><Export-Package>com.bw.osgi.provider.able</Export-Package><Bundle-Vendor>Baptiste Wicht</Bundle-Vendor></instructions></configuration></plugin></plugins></build> 
</project>

消费者:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>OSGiDmHelloWorldConsumer</groupId><artifactId>OSGiDmHelloWorldConsumer</artifactId><version>1.0</version><packaging>bundle</packaging><dependencies><dependency><groupId>OSGiDmHelloWorldProvider</groupId><artifactId>OSGiDmHelloWorldProvider</artifactId><version>1.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.0.2</version><configuration><source>1.6</source><target>1.6</target></configuration></plugin><plugin><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><extensions>true</extensions><configuration><instructions><Bundle-SymbolicName>OSGiDmHelloWorldConsumer</Bundle-SymbolicName><Bundle-Vendor>Baptiste Wicht</Bundle-Vendor></instructions></configuration></plugin></plugins></build>
</project>

我们可以使用maven install构建两个捆绑包。 因此,让我们在Felix中测试我们的东西:

wichtounet@Linux-Desktop:~/Desktop/osgi/felix$ java -jar bin/felix.jar
_______________
Welcome to Apache Felix Gogog! install file:../com.springsource.slf4j.org.apache.commons.logging-1.5.0.jar
Bundle ID: 5
g! install file:../com.springsource.slf4j.log4j-1.5.0.jar
Bundle ID: 6
g! install file:../com.springsource.slf4j.api-1.5.0.jar
Bundle ID: 7
g! install file:../log4j.osgi-1.2.15-SNAPSHOT.jar
Bundle ID: 8
g! install file:../com.springsource.net.sf.cglib-2.1.3.jar
Bundle ID: 9
g! install file:../com.springsource.org.aopalliance-1.0.0.jar
Bundle ID: 10
g! install file:../org.springframework.core-2.5.6.SEC01.jar
Bundle ID: 11
g! install file:../org.springframework.context-2.5.6.SEC01.jar
Bundle ID: 12
g! install file:../org.springframework.beans-2.5.6.SEC01.jar
Bundle ID: 13
g! install file:../org.springframework.aop-2.5.6.SEC01.jar
Bundle ID: 14
g! install file:../spring-osgi-extender-1.2.1.jar
Bundle ID: 15
g! install file:../spring-osgi-core-1.2.1.jar
Bundle ID: 16
g! install file:../spring-osgi-io-1.2.1.jar
Bundle ID: 17
g! start 5 7 8 9 10 11 12 13 14 15 16 17
log4j:WARN No appenders could be found for logger (org.springframework.osgi.extender.internal.activator.ContextLoaderListener).
log4j:WARN Please initialize the log4j system properly.
g! install file:../OSGiDmHelloWorldProvider-1.0.jar
Bundle ID: 18
g! install file:../OSGiDmHelloWorldConsumer-1.0.jar
Bundle ID: 19
g! start 18
g! start 19
g! Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
stop 19
g!

如您所见,它运行完美!

总之,Spring Dm确实使使用OSGi的开发更加容易。 使用Spring Dm,您还可以启动捆绑包。 它还使您可以制作Web捆绑包并轻松使用OSGi纲要的服务。

以下是这两个项目的来源:

  • OSGiDmHelloWorldProvider来源
  • OSGiDmHelloWorldConsumer来源

这是两个内置的Jars:

  • OSGiDmHelloWorldProvider-1.0.jar
  • OSGiDmHelloWorldConsumer-1.0.jar

这是完整的文件夹,包括Felix和Spring Dm: osgi-hello-world.tar.gz

参考: OSGI和Spring动态模块–来自我们的JCG合作伙伴 Baptiste Wicht的 @ @Blog(“ Baptiste Wicht”)的 Simple Hello World 。

相关文章 :
  • OSGi –带有服务的简单Hello World
  • OSGi将Maven与Equinox结合使用
  • 真正的模块化Web应用程序:为什么没有开发标准?
  • Java模块化方法–模块,模块,模块

翻译自: https://www.javacodegeeks.com/2011/11/osgi-and-spring-dynamic-modules-simple.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/374333.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言代码规范(五)函数参数个数

一个函数的参数的数目过多&#xff08;尤其是超过8个&#xff09;显然是一种不可取的编程风格。参数的数目直接影响调用函数的速度&#xff0c;参数越多&#xff0c;调用函数越慢。 参数的数目少&#xff0c;程序就显得精练、简洁&#xff0c;这有助于检查和发现程序中的错误。…

vijos P1740 聪明的质检员

题目链接:传送门 题目大意:给你n个物品&#xff0c;每件物品有重量 W 和价值 V&#xff0c;给m个区间&#xff0c;和一个标准值。(n,m最大200000) 要求找到一个值x&#xff0c;使得m个所有区间的权值和与标准值的差的绝对值最小。单个区间权值计算公式(数目num0&#xff0c;价值…

为什么有的开关电源需要加自举电容?

一、什么是自举电路&#xff1f; 1.1 自举的概念 首先&#xff0c;自举电路也叫升压电路&#xff0c;是利用自举升压二极管&#xff0c;自举升压电容等电子元件&#xff0c;使电容放电电压和电源电压叠加&#xff0c;从而使电压升高。有的电路升高的电压能达到数倍电源电压。…

VS2010报错 error:LINK1123:转换到COF期间失败,文件无限或损坏

右键工程-配置属性-清单工具-输入和输出&#xff0c;嵌入清单一项重新选择为否&#xff0c;如下图 修改后重新生成和运行&#xff0c;发现程序正常运行了。

springboot 整合mybatis_SpringBoot整合Mybatis、MybatisPuls

文末视频讲解SpringBoot的版本是2.2.0一、整合Mybatis1-1、引入pom文件<dependency> <groupId>mysqlgroupId> <artifactId>mysql-connector-javaartifactId> <version>8.0.19version> dependency> <dependency> &l…

iOS 开发中遇到的问题

1. 关于纠结很久的KVO崩溃问题&#xff0c;其真正原因是&#xff0c;在删除roomItem的KVO之前,将这个对象已经赋值为nil,所以实际上并没有删除他的observer&#xff0c;因此而崩溃&#xff1b;长时间纠结的原因是受.cxx_destruct影响了思路 2.拷贝block 因为block变量默认是声明…

为旧版代码创建存根–测试技术6

任何阅读此博客的人都可能已经意识到&#xff0c;目前我正在开发一个包含大量旧代码的项目&#xff0c;这些旧代码庞大&#xff0c;扩展且编写时从未进行过任何测试。 在使用此遗留代码时&#xff0c;有一个行为异常的类非常普遍&#xff0c;整个团队都一次又一次地犯错。 为了…

C学习杂记(一)常见误会

一、sizeof是关键字&#xff0c;不是函数。 二、strlen是函数。

python性能解决_我们如何发现并解决Python代码中性能下降的问题

Python部落(python.freelycode.com)组织翻译&#xff0c;禁止转载&#xff0c;欢迎转发。 作者&#xff1a;Omer Lachish 最近&#xff0c;我们已经开始使用RQ库代替Celery库作为我们的任务运行引擎。第一阶段&#xff0c;我们只迁移了那些不直接进行查询工作的任务。这些任务包…

easyui $.parser.parse 页面重新渲染

一些dom元素是动态拼接上的easui的样式&#xff0c;由于页面已经渲染过了&#xff0c;所以需要手动执行渲染某个部件或者整个页面 $.parser.parse(); // parse all the page $.parser.parse(#cc); // parse the specified node $.parser.parse($("#grid").parent());…

Java EE6装饰器:在注入时装饰类

软件中常见的设计模式是装饰器模式 。 我们上一堂课&#xff0c;然后在它周围包装另一堂课。 这样&#xff0c;当我们调用类时&#xff0c;我们总是在到达内部类之前经过周围的类。 Java EE 6允许我们通过CDI创建装饰器&#xff0c;作为其AOP功能的一部分。 如果我们想实现仍然…

C语言代码规范(六)浮点型变量逻辑比较

无论是float还是double类型的变量&#xff0c;都有精度限制。所以一定要避免将浮点变量用""或"!"与数字比较&#xff0c;应该设法转化成为">"或"<"形式。 不建议使用的例子&#xff1a; if(0.0 x) if(0.0 ! x) 强烈推荐的例…

图灵机器人调用数据恢复_机器人也能撩妹?python程序员自制微信机器人,替他俘获女神芳心...

机器人也有感情还记得王传君饰演的《星语心愿之再爱》这部电影吗&#xff1f;王传君饰演的天才程序员“王鹏鹏”因工作原因不能陪伴照顾身在异地的女朋友“林亦男”&#xff0c;呆萌宅男“王鹏鹏”开发出一款以自己为原型的“王鹏鹏8.0”程序去陪伴异地恋的女友&#xff0c;后来…

Spark排错与优化

一. 运维 1. Master挂掉,standby重启也失效 Master默认使用512M内存&#xff0c;当集群中运行的任务特别多时&#xff0c;就会挂掉&#xff0c;原因是master会读取每个task的event log日志去生成spark ui&#xff0c;内存不足自然会OOM&#xff0c;可以在master的运行日志中看到…

在MySQL上使用带密码的GlassFish JDBC安全性

我在该博客上最成功的文章之一是有关在GlassFish上使用基于表单的身份验证来建立JDBC安全领域的文章 。 对这篇文章的一些评论使我意识到&#xff0c;要真正使它安全&#xff0c;应该做的还很多。 开箱即用的安全性 图片&#xff1a; TheKenChan &#xff08; CC BY-NC 2.0 &a…

mgo写入安全机制

mgo写入安全机制 mongo写入安全mgo写入安全mongo写入安全 mongo本身也有一整套的写入安全机制,但是在这篇的内容里只介绍一小部分相关部分.先放一个链接可以跳过本节不看直接看这个 链接. WriteConcern.NONE:没有异常抛出WriteConcern.NORMAL:仅抛出网络错误异常&#xff0c;没…

C学习杂记(二)笔试题:不使用任何中间变量如何将a、b的值进行交换

常见的方法如下 void swap1(int *a, int *b) {int temp *a;*a *b;*b temp; } 不使用中间变量的方法 void swap2(int *a, int *b) {*a *a *b;*b *a - *b;*a *a - *b; } 这种方法是不可取的&#xff0c;因为ab和a-b的运算可能会导致数据溢出。 void swap3(int *a, in…

利用python进行数据分析_利用python进行数据分析复现(1)

&#xfeff;一直以来&#xff0c;都想学习python数据分析相关的知识&#xff0c;总是拖拖拉拉&#xff0c;包括这次这个分享也是。《利用python进行数据分析 第2版》是一次无意之间在简书上看到的一个分享&#xff0c;我决定将很详细。一直都想着可以复现一下。但总有理由&…

在运行时交换出Spring Bean配置

如今&#xff0c;大多数Java开发人员都定期与Spring打交道&#xff0c;而我们当中的许多人已经熟悉了Spring的功能和局限性。 最近&#xff0c;我遇到了一个我从未遇到过的问题&#xff1a;引入了基于运行时引入的配置来重新连接Bean内部的功能。 这对于简单的配置更改或交换掉…

Proximal Algorithms--Accelerated proximal gradient method

4.3 Accelerated proximal gradient method&#xff1a; 加速近端梯度方法&#xff1a; 基本的近端梯度方法的所谓的“加速”版本&#xff0c;就是在算法中包含了一个外推(extrapolation)步骤&#xff0c;一个简单的版本是&#xff1a; yk1:xkωk(xk−xk−1)xk1:proxλkg(yk1−…