Spring DM并不是OSGi规范的实现,也就是说它不是OSGi容器。它只是一套用于在OSGi环境中将Spring Bean注册发布为OSGi服务的工具。它充分利用Spring的特性,将OSGi与Spring无缝的加以结合,实现了Spring的模块化开发。
1. 在使用Spring DM进行开发过程中发现的问题:
虽然Spring DM改进了OSGi原本的DS开发,使用Spring Bean来完成服务的注册。但是对于“懒惰”的程序员来说还是太过繁琐,首先需要在XML中注册SpringBean,然后要使用SpringDM提供的特殊命名空间(<osgi:service>)发布服务,最后当需要引入一个OSGi服务时又要使用SpringDM提供的另外一个特殊命名空间(<osgi:reference>)来引入服务。对于一个只有十几个Bean的应用程序来说,这些配置量也无所谓,但是当应用程序的Bean发展到上百个的时候,这简直就是配置噩梦。尤其是在多人合作开发的环境下,经常会发生遗漏配置的情况,一旦遗漏则OSGi服务将无法启动,并且要在上百个Bean配置XML文件中查找到底是哪个遗漏了,的确也是一件体力活(这正是IT民工的悲惨命运)。
当然Spring DM的开发团队也想到了这点,为我们开发人员提供了Annotation的选项,这样可以大大减少XML的配置量(这里我们不争论XML和Annotation孰优孰劣)。但是不知为何,Spring DM只提供了引入服务的Annotation,并没有提供发布OSGi服务的Annotation,这让我很费解?其次,由于SpringDM是在JDK1.4环境下编译的,所以默认情况下Annotation的功能是Disabled的。这又让我很费解?到底让我们用不用Annotation!
2. 问题的解决方案:
针对上述的问题,我们可以通过以下方法解决;
1) 如何启用Spring DM的Annotation功能
通过阅读Spring DM提供的官方文档,让我很莫名,关于Annotation的介绍只有寥寥数语,而且还是放在附录中介绍的。可能是我的英文水平太烂,总之一句话,没看懂!后来从解决其他问题的过程中得到了启示,终于开启了SpringDM的Annotation功能。
第一步,创建一个Fragment类型的Bundle,具体的目录结构如下图所示:
这里主要关注2个文件,一个是extender.xml文件和MANIFEST.MF文件。
第二步,创建extender.xml文件:
在上图所示的目录结构中创建一个extender.xml文件,这个文件用于覆盖SpringDM Extender的配置选项。因为默认情况下是不支持Annotation的,所以要将指定的属性值设置为开启状态,才能使用Annotation功能。配置文件的内容如下:
这个配置文件其实就是一个Spring Bean的配置文件。将process.annotations属性设置成true,就开启了Spring DM的Annotation功能。
第三步,创建MANIFEST.MF文件,这个文件是Bundle的属性配置文件,我们在这个文件中指定Fragment-Host属性,具体内容如下:
其中我们要关注的是Fragment-Host属性,这里指定为org.springframework.osgi.extender,表示在extender Bundle启动之前先启动ftps-extender-config这个Bundle,这样就将默认的属性值更新为我们设置的属性值。
第四步,在Spring的XML配置文件中注册处理Annotation的处理器Bean,如下所示:
通过上述4个步骤,我们就开启了Spring DM的Annotation功能。
以下例子展示如何使用Spring DM的Annotation功能:
其中@ServiceReference就是引入OSGi服务的Annotation,它等效于XML中的<osgi:reference/>配置项。
2) 编写自己的Annotation实现OSGi服务的发布:
胜利的喜悦还没维持多久,新的问题又随之而来。既然我们已经有引入OSGi服务的Annotation,为什么发布OSGi服务的时候不能使用Annotation呢?我们仍然在继续编写一大坨苦涩的OSGi配置项,这种工作即枯燥又乏味。但是寻遍SpringDM的所有官方文档,包括SpringDM提供的Annotation扩展包源代码,都没有找到发布OSGi服务的Annotation。Google一下,大致都是提问的,没有回答问题的。没有办法,只能靠自己。经过对SpringDM源代码的阅读以及使用BEBUG来查看代码流程的走向,终于了解了SpringDM将Spring
Bean发布为OSGi服务的大致方法。其中最关键的对象就是:OsgiServiceFactoryBean。这个工厂bean就是将SpringBean发布为OSGi服务的关键类。这个类并不难懂,有兴趣的朋友可以阅读一下这个类的源代码。由于我们是解决问题的文章,不是谈理论的文章,所以我们继续看实现方案:
首先介绍一下解决方案的大致流程。1)通过编写一个实现了BeanPostProcessor接口的处理器类,我们就可以对Bean的生命周期进行控制。2)在容器中的某个Bean被初始化之后,我们拦截这个Bean,并获取该Bean上是否写了注册OSGi服务的Annotation。3)如果是,则实例化OsgiServiceFactoryBean对象,设置相关的属性值,并调用OsgiServiceFactoryBean对象的afterPropertiesSet方法,进行OSGi服务的注册和发布。最后返回该OsgiServiceFactoryBean对象。同时将该对象的引用放入一个集合中保存用于OSGi服务的注销。4)当处理器类被销毁时,对集合中的所有OsgiServiceFactoryBean对象执行destroy方法,完成OSGi服务的注销操作。
先来看Annotation的代码,很简单,如下所示:
ElementType.TYPE指定这个Annotation只能用于类声明,接口声明上。
接着是处理器的实现代码,先关注类签名:
这里需要关注的是实现的几个接口的用途。实现BundleContextAware接口是为了在处理器中获取Bundle上下文对象。实现BeanClassLoaderAware接口是为了在处理器中获取ClassLoader对象,这些对象都是注册发布OSGi服务所必须使用的对象。而继承InstantiationAwareBeanPostProcessorAdapter适配器是为了在Spring Bean初始化完之后给我们一个机会进行定制的特殊处理。我们需要覆盖的是InstantiationAwareBeanPostProcessorAdapter类的postProcessAfterInitialization方法。该方法在Spring
Bean初始化之后执行。我们来看这个方法的实现,如下所示:
代码中的注释已经很好的说明了各逻辑块的实现目的,不再赘述。其中需要关注createExporter方法,这个方法是创建OsgiServiceFactoryBean对象的。如下所示:
代码很简单,就是实例化对象,并调用注册发布OSGi服务的方法。其实发布一个OSGi服务只需要三个参数:Bean名称,Bean对象,Bean实现接口类型的数组,这个和XML中的配置属性一一对应:
<osgi:service ref="systemConfigureServiceBean" interface="org.storevm.ftps.biz.service.core.SystemConfigureService"/>
其中ref属性对应Bean名称以及一个Bean对象的引用,interface属性对应Bean实现接口类型的一个数组。
该方法中用到的一些其他实例变量的定义如下:
最后来看一下OSGi服务的注销实现,代码如下:
注销服务就是将先前注册时保存下来的OsgiServiceFactoryBean对象集合进行destroy方法的调用。
3. 启用发布OSGi服务的Annotation:
相比较开启SpringDM自带的Annotation,我们这个Annotation的启用方法要简单的多。只要在Spring的XML中注册这个处理器Bean就可以了,代码如下:
以下实例代码展示了如何使用使用Annotation发布一个OSGi服务发布:
其中@OsgiService就是注册发布OSGi服务的Anntation。到此我们终于实现了使用Annotation来发布注册OSGi服务以及引入OSGi服务,我们不再需要在XML中配置那一大坨无聊的OSGi服务配置了。最后引用一句名言:任何发明创造源自于“懒惰”
分享到:
相关推荐
《Spring Roo注解详解及其在Maven项目中的...结合Maven的依赖管理,开发者可以方便地在项目中使用这些注解,从而提升开发效率和代码质量。理解和熟练运用这些注解,对于掌握Spring Roo并构建高效的企业级应用至关重要。
它大大简化了在Spring应用中基于业界使用广泛的Ehacche-2.0版本实现缓存的技术,1.1.2版本的ehcache-spring-annotations刚刚发布不久,在本文中,我将会介绍如何在一个web工程时使用ehcache-spring-annotations实现...
ehcache-spring-annotations-1.2.0.jar
标题中的"jquery+json+structs+spring+hibernate-annotations+maven"是一个典型的Java Web开发技术栈,涵盖了前端到...在实际开发中,理解并熟练掌握这些技术的原理和使用方法,对于提升开发效率和代码质量至关重要。
6. **实战示例**:提供实际的项目案例,演示如何在 Spring 2.0 应用中配置和使用 Hibernate Annotations,包括数据库初始化、数据存取和事务处理等。 7. **性能优化**:讨论 Hibernate 的缓存策略、批处理操作和懒...
ehcache-spring-annotations-1.1.2.jar
在Spring框架的历史中,注解经历了从启蒙到黄金时代,再到完善的各个阶段,从Spring 1.x到5.x,其功能和应用越来越广泛。 1. **Spring 注解驱动编程发展历程** - **启蒙时代**:Spring 1.x时期,主要依赖XML配置来...
6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application context情况下的处理 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来...
**Ehcache配置** 在Spring中通常通过XML或Java配置完成。XML配置中,我们可以定义`<ehcache:config>`和`<ehcache:cache>`元素来设置Ehcache的配置属性,如缓存的大小、过期策略等。而Java配置则使用`@EnableCaching`...
在IT行业中,Jackson库是Java领域广泛使用的JSON处理库,特别是在Spring框架中。"jackson-annotations"、"jackson-core"和"jackson-databind"是Jackson库的三个核心模块,它们协同工作,提供了强大的JSON序列化和反...
jar包,官方版本,自测可用
在IT行业中,Hibernate、Spring和Hibernate Annotations是三个非常重要的框架,尤其在Java企业级应用开发中扮演着核心角色。这些框架极大地简化了数据库操作、对象关系映射(ORM)以及应用程序的依赖注入和管理。 ...
- **@ModelAttribute**:用于将数据绑定到模型(Model),可以在控制器的方法参数或返回值中使用。 #### AspectJ注解(AspectJ Annotations) AspectJ是AOP的一种实现,Spring框架支持AspectJ的注解风格,使得开发者...
在使用Apache Dubbo作为服务治理框架时,可能会遇到“Multiple annotations found at this line”这样的错误提示。这个错误通常发生在解析XML配置文件时,表明在同一行内发现了多个注解,这在XML规范中是不被允许的...
4. **JSR-303数据校验**:Spring 3.0集成了JSR-303标准,提供了对Bean属性的数据校验支持,通过@Valid注解可以在服务层和控制器层进行数据验证。 5. **MVC框架增强**:Spring 3.0的Web MVC框架有了重大提升,包括...
在这个测试用例中,我们使用 @Autowired 注解来注入服务消费者,然后使用这个服务消费者来调用服务提供者的方法。 使用 Spring Cloud Feign 可以轻松地实现服务间的相互调用。通过使用 Feign 客户端,我们可以方便...
6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...
在描述中提到的`jboss-logging.jar`和`jboss-logging-annotations.jar`则是JBoss组织提供的日志服务。`jboss-logging.jar`是一个高效的、可扩展的日志框架,支持多种日志实现,如Log4j、Java.util.logging和SLF4J。...
Android Annotations框架是一个强大的工具,它通过使用Java注解(Annotations)来简化Android应用的开发...在实践中,开发者可以通过不断地尝试和实践,掌握Android Annotations的用法,从而更高效地构建Android应用。