`
georgezeng
  • 浏览: 103430 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

OSGI下的web应用开发(5)

阅读更多

这一节将对Dao Interface Bundle 和 Dao implementation Bundle进行开发。

 


  
上图是Dao层的设计。为了尽可能的还原真实的设计架构,这里设计了一个BaseDao,用来定义最基本的Dao操作。
然后有一个HibernateBaseDao的抽象类继承它并实现这些基本操作。然后定义了一个ContactDao,这个dao就是联系人相关业务的Dao接口,以及它的实现ContactDaoImpl。图中我们可以看到模块的划分情况,接口是一个bundle,实现是另一个bundle。

  • Dao Interface Bundle的开发
(1)首先创建一个Bundle Project项目(创建的详细过程已经在前面的章节给出,请参考前面),定义项目名称为net.georgezeng.test.dao。

(2)定义上面图中的两个接口

BaseDao的定义:

package net.georgezeng.test.dao;

import java.util.List;

public interface BaseDao<T> {
  void save(T t);
  T get(Long id);
  List<T> findList(T t); 
}
 
ContactDao的定义如下:

package net.georgezeng.test.dao;

import net.georgezeng.test.domain.Contact;

public interface ContactDao extends BaseDao<Contact> {
}

(3)MANIFEST.MF的定义
import:
当前的Bundle中有用到了domain bundle下的包,因此需要引入net.georgezeng.test.domain,如图


 
export:
我们还需要把接口进行export才能让Dao Implementation Bundle进行引用,如图


 
注意:这里在引入的时候可能会有问题,因为bundle的引用默认是通过在Virgo server的repository目录中获取的,但是目前我们自己开发的bundle是不可能放在那个目录下面的,这个时候就没办法找到那个需要import的包了,所以我们需要做一点小操作,让IDE可以找到这个包。具体操作步骤如下:
1)在Package Explorer中选中当前的项目,如图


 
我这里的项目名称是net.georgezeng.test.dao2, 然后右键点击弹出菜单,选择最下面的Properties选项,进入下图



 
选中Project References,然后在勾选上net.georgezeng.test.domain进行项目关联,这样就可以使import搜索到需要的package了。

2)这个应该是属于IDE工具本身的一个小bug,有的时候我们引入项目关联后虽然可以import需要的包了,但是还是提示找不到这个包,这个时候我们可以先将之前已经import的内容remove,再重新import一次就可以了。(后面讲到的项目间的引用都是通过这种方式实现)

这样我们的Dao Interface Bundle就开发完毕了,接下来我们来开发Dao Implementation Bundle

  • Dao Implementation Bundle
新建Bundle Projecton工程,命名为net.georgezeng.test.dao.impl。
(1)Dao的实现
(1.1)HibernateBaseDao的定义

package net.georgezeng.test.dao.hibernate;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import net.georgezeng.test.dao.BaseDao;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public abstract class HibernateBaseDao<T> extends HibernateDaoSupport implements BaseDao<T> {
  protected Class<T> entityClass;

  @Autowired
  public void init(SessionFactory sessionFactory) {
    super.setSessionFactory(sessionFactory);
  }

  public HibernateBaseDao() {
    entityClass = getEntityClass();
  }

  @Override
  public void save(T t) {
    getHibernateTemplate().save(t);
  }

  @Override
  public T get(Long id) {
    return getHibernateTemplate().get(entityClass, id);
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<T> findList(T t) {
    return getHibernateTemplate().findByExample(t);
  }

  @SuppressWarnings("unchecked")
  protected Class<T> getEntityClass() {
    Type type = getClass().getGenericSuperclass();
    Class<T> result = null;
    if (type instanceof ParameterizedType) {
      ParameterizedType pType = (ParameterizedType) type;
      result = (Class<T>) pType.getActualTypeArguments()[0];
    }
    return result;
  }

}
 
(1.2) ContactDaoImpl的定义

package net.georgezeng.test.contact.dao;

import net.georgezeng.test.dao.ContactDao;
import net.georgezeng.test.dao.hibernate.HibernateBaseDao;
import net.georgezeng.test.domain.Contact;

import org.springframework.stereotype.Repository;

@Repository("ContactDao")
public class ContactDaoImpl extends HibernateBaseDao<Contact> implements ContactDao {
}
 
这里我们需要给ContactDaoImpl定义一个bean id,这样才能在后面曝露服务的时候引用到这个bean,即@Repository里的"ContactDao"

(2)MANIFEST.MF定义

import:


 

export: 这个bundle没有需要export的内容

(3)spring配置

(3.1)osgi-context.xml

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

	<osgi:reference id="dataSource" interface="javax.sql.DataSource" />

	<osgi:service ref="transactionManager" interface="org.springframework.transaction.PlatformTransactionManager" context-class-loader="service-provider" />
	
	<osgi:service ref="ContactDao" interface="net.georgezeng.test.dao.ContactDao" />



</beans>
 
 在前面的章节中Datasource Bundle已经曝露了dataSource的服务,这里我们需要引入,通过

<osgi:reference id="dataSource" interface="javax.sql.DataSource" />
我们就把服务引入了


(3.2)appContext.xml

<?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"
	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.xsd">

	<context:annotation-config />
	<context:component-scan base-package="net.georgezeng.test" />
	
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="schemaUpdate" value="false"></property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
			</props>
		</property>
		<property name="annotatedClasses">
			<list>
				<value>net.georgezeng.test.domain.Contact</value>
			</list>
		</property>
	</bean>

	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>


</beans>
 
我们需要定义一个sessionFactory用于对Hibernate进行管理,请看其中对dataSource的引入

<property name="dataSource">
			<ref bean="dataSource" />
		</property>
这里的bean 属性的值引用的是上面定义的osgi:reference标签中的id属性的值

接着我们还要定义一个transactionManager,用来对事务进行控制。这个transactionManager将会以服务的方式发布到OSGI中,让service层可以使用这个服务。
在回头看osgi-context.xml中对服务的定义,

<osgi:service ref="transactionManager" interface="org.springframework.transaction.PlatformTransactionManager" context-class-loader="service-provider" />
这里有一个很重要的属性需要设置,就是context-class-loader,需要设置为service-provider,目的是让service调用这个服务的时候使用的是服务提供者(即Dao Implementation Bundle)的classloader,这样就可以正确的调用hibernate的API,否则将会抛错提示hibernate的API不可见。
其实我们也可以让transactionManager单独作为一个模块,但是意义不大,这里不做讨论。

我们还看到曝露了一个ContactDao的服务,这里ContactDao的id值正是与@Repository中的值相对应的,这样service层就可以使用DAO的服务了

至此dao层的开发就结束了

附上该项目的源码



  • 大小: 16.4 KB
  • 大小: 16.7 KB
  • 大小: 13.2 KB
  • 大小: 110.4 KB
  • 大小: 98.3 KB
2
0
分享到:
评论
8 楼 Tom.X 2016-02-27  
7 楼 xiaohei520104 2015-07-06  
楼组辛苦了,关于OSGi web的demo资料很少,非常感谢你的分享。我在按照文章步骤开发下来出现一个错误:就是在框架构造文章所说的HibernateBaseDao类时注入SessionFactory的方法报错,具体错误如下:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.osgi.demo.framework.orm.dao.impl.HibernateBaseDao.init(org.hibernate.SessionFactory); nested exception is java.lang.NoClassDefFoundError: Ljavax/transaction/TransactionManager;
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
... 18 common frames omitted
Caused by: java.lang.NoClassDefFoundError: Ljavax/transaction/TransactionManager;
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:2387)
at java.lang.Class.getDeclaredFields(Class.java:1796)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:373)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotationBeanPostProcessor.java:321)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:830)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:493)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:848)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:790)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:551)
... 20 common frames omitted
Caused by: org.eclipse.virgo.kernel.osgi.framework.ExtendedClassNotFoundException: javax.transaction.TransactionManager in KernelBundleClassLoader: [bundle=org.springframework.orm_3.1.0.RELEASE]
at org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader.loadClass(KernelBundleClassLoader.java:150)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 36 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.transaction.TransactionManager
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:455)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader.loadClass(KernelBundleClassLoader.java:146)
... 37 common frames omitted
6 楼 xxuan1985 2012-07-27  
Caused by: org.eclipse.virgo.kernel.osgi.framework.ExtendedClassNotFoundException: org.hibernate.cfg.Configuration in KernelBundleClassLoader: [bundle=org.springframework.orm_3.0.5.RELEASE]
at org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader.loadClass(KernelBundleClassLoader.java:139)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
... 26 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.hibernate.cfg.Configuration
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader.loadClass(KernelBundleClassLoader.java:135)
... 27 common frames omitted
5 楼 xxuan1985 2012-07-27  
为什么我配置后启动后台报错了呢?
com.springsource.org.hibernate-3.3.2.GA.jar 这个bundle我import了的。
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [bundleentry://153.fwk27582163/META-INF/spring/vas-base.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.orm.hibernate3.LocalSessionFactoryBean]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/hibernate/cfg/Configuration at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:965) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:911) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:563) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895) at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:60) at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:325) at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85) at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:290) at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:137) at org.eclipse.virgo.kernel.agent.dm.ContextPropagatingTaskExecutor$2.run(ContextPropagatingTaskExecutor.java:95) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619) 
4 楼 georgezeng 2012-05-11  
heavenlee 写道
博主这个系列的文章写的很详细,适合初级选手入门,例子讲的很贴近实际企业级开发,最近公司也想向组件化开发的方向发展,希望向你取经,希望能和你认识,我的EMAIL:heavenleetj@gmail.com



150023448,可以加入这个群一起讨论
3 楼 heavenlee 2012-05-11  
博主这个系列的文章写的很详细,适合初级选手入门,例子讲的很贴近实际企业级开发,最近公司也想向组件化开发的方向发展,希望向你取经,希望能和你认识,我的EMAIL:heavenleetj@gmail.com
2 楼 georgezeng 2011-07-23  
jjw21 写道
非常易懂,期待继续。

另外能否先整体给应用特性个全面介绍,比如热部署、多版本、集群等特性。


后面将会有另外的篇幅来讲解如何使用virgo server,就会提到如何热部署了。
多版本我之前在OSGI的心得体会下有提到过的,也可以查看相关的资料。
至于集群目前我还没有研究,可以等有时间的时候再看看然后再搞个例子出来:)
1 楼 jjw21 2011-07-22  
非常易懂,期待继续。

另外能否先整体给应用特性个全面介绍,比如热部署、多版本、集群等特性。

相关推荐

    基于OSGi和Spring开发Web应用.doc

    "基于OSGi和Spring开发Web应用" OSGi(Open Service Gateway Initiative)是一种面向服务的框架,能够提供动态模块部署和管理的能力。Spring 是一个轻量级的J2EE开发框架,特点是面向接口编程和非侵入式的依赖注入...

    基于OSGi的Web应用开发系列(全).pdf

    **基于OSGi的Web应用开发**是现代软件开发中的一种技术实践,它允许开发者构建模块化、可扩展和可维护的Web应用。OSGi(Open Service Gateway Initiative)是一种开放的标准,提供了一种服务导向的、模块化的Java...

    基于OSGi和Spring开发Web应用

    综上所述,基于OSGi和Spring开发Web应用不仅能够充分利用OSGi的模块化优势和Spring的依赖注入机制,还能借助dmServer和SpringSource应用平台等工具,实现更加高效、灵活和可靠的企业级应用开发。

    基于OSGi和Spring开发Web应用教程

    总的来说,基于OSGi和Spring的Web应用开发结合了两者的优点:OSGi提供了模块化和动态部署的能力,而Spring则带来了方便的依赖管理和服务注册。通过Spring-DM,开发者可以在OSGi环境中享受到Spring的便利,构建更灵活...

    行业分类-设备装置-基于OSGi的Web应用开发平台权限管理自适应设计方法.zip

    在基于OSGi的Web应用开发平台中,权限管理涉及到用户、角色和资源的控制。传统的权限管理通常采用固定的角色-权限模型,但在自适应设计中,系统需要根据用户的行为、环境或者业务需求动态调整权限分配。这通常通过...

    OSGi与Web容器的整合

    将OSGi与Web容器整合,可以实现更加灵活和模块化的Web应用开发和部署。 **1. OSGi Bundle放入Web容器中运行** 这是通过像Equinox的Servlet Bridge这样的技术实现的,它充当了一个桥梁,让OSGi Bundle可以在传统的...

    基于OSGi和Spring开发Web应用的Demo

    在基于OSGi和Spring的Web应用开发中,通常会将业务逻辑、服务接口和Web层分别封装在不同的模块中。根据压缩包子文件的文件名称,我们可以推测这些文件可能代表了这样的模块结构: 1. `...

    基于OSGI的Web开发例子

    5. 测试“Hello World”:通过访问特定的URL,验证“Hello World”程序是否正常工作,确保OSGi环境下的Web应用已经成功部署。 在OSGi环境下开发Web应用的好处在于,我们可以独立更新和管理各个组件,避免了传统的...

    开发一个简单的 OSGi Web 应用实例

    本教程旨在通过一个具体的示例来介绍如何使用OSGi框架开发一个简单的Web应用。这个示例应用能够计算两个数字的和或乘积,并展示了OSGi bundle的动态部署特性。 #### 二、项目背景及目标 **背景:** OSGi (Open ...

    基于OSGi和Spring开发企业级Web应用

    ### 基于OSGi和Spring开发企业级Web应用 #### OSGi与Spring结合的重要性 ...综上所述,将OSGi和Spring结合起来使用,可以有效地解决企业级应用开发中面临的许多挑战,是一种值得推广的技术方案。

    基于 OSGi 和 Spring 开发 Web 应用

    基于 OSGi 和 Spring 开发 Web 应用

    基于VirgoServer进行Spring Osgi Web开发

    在本文中,我们将深入探讨如何基于VirgoServer进行Spring Osgi Web开发,这是一个涉及OSGi容器、Spring框架和Web应用程序的集成技术。首先,我们需要确保拥有正确的开发环境和工具,包括Spring Tool Suite (STS),...

    osgi 在web容器中部署

    这些工具可以将OSGi环境集成到Tomcat中,允许OSGi bundles作为Web应用的一部分运行。 Apache Felix WebConsole是一个基于Web的管理界面,可以用来管理和控制OSGi环境。你可以将其作为一个OSGi bundle部署到Tomcat中...

    自己开发的OSGi Web Console

    1、自己开发的OSGi Web Console,适用于实现了OSGi规范的Equinox、Felix等...2、展示了如何把OSGi框架作为一个组件嵌入到现有的未基于OSGi开发的Web应用当中,在Web应用中可获取OSGi中的Service以增加应用的灵活性。

    OSGI中包含web服务器配置需要的jar.zip

    6. **开发和部署**: 使用这些jar文件,开发者可以按照博客"OSGi环境下建立Web工程的Hello World"中的步骤,创建并部署OSGI兼容的Web应用。这通常涉及编写bundle的MANIFEST.MF文件来声明导出和导入的包,以及如何配置...

    OSGi Web示例工程

    Web示例工程是使用OSGi技术构建的一个具体应用,通常包括了如何在OSGi环境中部署和运行Web应用程序的实例。 在OSGi框架中,Equinox是Eclipse基金会提供的一个实现,它是OSGi规范的主要实现之一,广泛应用于服务器端...

Global site tag (gtag.js) - Google Analytics