`
codecook
  • 浏览: 42284 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

封装Hibernate成Bundle

阅读更多
为什么要封装?
1,目前Hibernate没有提供Hibernate Bundle,只能自己封装.
2,封装第3方jar包是开发osgi程序的必备技能.

扩展模式(extender pattern):
介绍在此:http://felix.apache.org/site/extender-pattern-handler.html
不要被它高深的名字吓倒,简单地说就是一个Bundle负责监听,查看其他Bundle是否符合某种特征,如果符合,则对该bundle怎么怎么样;如果不符合,又对bundle怎么怎么样.
我们把hibernate.cfg.xml文件放在felix根目录下的cfg目录,把实体的映射文件放在各自实体bundle的mappingresource目录下.1个bundle负责监听其它bundle的安装和卸载,当bundle安装时,查看它的MANIFEST.MF中是否有HibernateEntity-Class属性,如果有,则载入mappingresource目录下的映射文件.

构建工具maven
  请使用maven吧!不要因为ant已经很强大而抗拒它. Felix提供了maven-bundle-plugin 这个  Bundle来构建其它bundle.它内部是使用了具有osgi瑞士军刀之称的bnd.

Action:
我们决定分装3个Bundle:
  1,Hibernate Lib Bundle.里面封装了Hibernate类库.
  2,Hibernate Service Bundle.该Bundle提供获得Session服务.
  3,Hibernate EntityRegister Bundle.该Bundle负责监听其他Bundle,使用了扩展模式.

封装Hibernate Lib Bundle
  把所有Hibernate相关的jar包统统放进去吧(明显不合理,但简单可行).Export一些别人需要使用的包吧.
 
封装ibernate Service Bundle
  只需提供一个接口即可.


public interface HibernateService {

	/**
	 * 获得Hibernate Session
	 * @return
	 */
	public Session getSession();
}


封装Hibernate EntityRegister Bundle
   监听其它Bundle的安装,载入符合条件的Bundle的hibernate映射文件,注册HibernateService服务实体.

/**
 * 常量
 *
 */
public class HibernateConstants {
	
	/**
	 * 包含Hibernate实体的Bundle属性标签
	 */
	public static final String HibernateBundleTag = "HibernateEntity-Class";
	/**
	 * Bundle内包含Hibernate映射文件的默认目录
	 */
	public static final String DefaultHibernateMappingDir = "mappingresource";
}


public class HibernateServiceImpl implements HibernateService {
	private String CONFIG_FILE_LOCATION = System.getProperty("user.dir")
			+ "/cfg/hibernate.cfg.xml";

	private Configuration configuration;

	private SessionFactory sessionFactory;

	private final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
	
	public Session getSession() {
		Session session = threadLocal.get();
		if (null == session || !session.isOpen()) {
			session = sessionFactory != null
					? sessionFactory.openSession()
					: null;
			threadLocal.set(session);
		}
		return session;
	}

	public HibernateServiceImpl() {

	}

	public List<String> listMappingFiles(String location) {
		List<String> result = new ArrayList<String>();
		if (location.endsWith(".jar")) {
			JarFile jar;
			try {
				// 获取jar
				jar = new JarFile(location);
				// 从此jar包 得到一个枚举类
				Enumeration<JarEntry> entries = jar.entries();
				// 同样的进行循环迭代
				while (entries.hasMoreElements()) {
					// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
					JarEntry entry = entries.nextElement();
					String name = entry.getName();
					// 如果是以/开头的
					if (name.charAt(0) == '/') {
						// 获取后面的字符串
						name = name.substring(1);
					}

					// 如果前半部分和定义的包名相同
					if (!entry.isDirectory()
							&& name.startsWith(HibernateConstants.DefaultHibernateMappingDir)) {
						result.add(name);
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	public boolean init(Bundle bundle) {
		try {
			//载入Hibernate.cfg.xml文件
			loadHibernateCfg();
			//是否是HibernateEntityBundle
			if (isHibernateEntityBundle(bundle)) {
				//设置当前线程的ClassLoader为Bundle的ClassLoader
				setBundleClassLoaderToCurrentThread(bundle);
				// 遍历bundle内的映射文件,添加到configuration中
				loadHibernateMappingFiles(bundle);
			}
			sessionFactory = configuration.buildSessionFactory();
		} catch (HibernateException e) {
			System.out.println("sessionFactory建立错误" + e);
			return false;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 是否是HibernateEntityBundle
	 * @param bundle
	 * @return
	 */
	private boolean isHibernateEntityBundle(Bundle bundle) {
		return bundle.getHeaders().get(HibernateConstants.HibernateBundleTag) != null;
	}

	/**
	 *  遍历bundle内的映射文件,添加到configuration中
	 * @param bundle
	 * @throws UnsupportedEncodingException
	 */
	private void loadHibernateMappingFiles(Bundle bundle)
			throws UnsupportedEncodingException {
		String urlLocation = bundle.getLocation();
		urlLocation = java.net.URLDecoder.decode(urlLocation, "utf-8");
		String jarLocation = urlLocation.substring(6);
		List<String> mappingFilePathList = listMappingFiles(jarLocation);

		for (String filePath : mappingFilePathList) {
			InputStream is = Thread.currentThread()
					.getContextClassLoader()
					.getResourceAsStream(filePath);
			configuration.addInputStream(is);
		}
	}

	/**
	 * 设置当前线程的ClassLoader为Bundle的ClassLoader
	 * @param bundle
	 * @throws ClassNotFoundException
	 */
	private void setBundleClassLoaderToCurrentThread(Bundle bundle)
			throws ClassNotFoundException {
		System.out.println("this bundle contains hibernate entity");
		String[] clazzs = bundle.getHeaders()
				.get(HibernateConstants.HibernateBundleTag).toString()
				.split(",");
		if (clazzs != null && clazzs.length > 0) {
			ClassLoader bundleClassLoader = bundle.loadClass(clazzs[0])
					.getClassLoader();
			Thread.currentThread().setContextClassLoader(
					bundleClassLoader);
		}
	}

	/**
	 * 载入Hibernate.cfg.xml文件
	 */
	private void loadHibernateCfg() {
		File file = new File(CONFIG_FILE_LOCATION);
		configuration = new Configuration();
		configuration.configure(file);
	}
}







分享到:
评论
3 楼 icecream0 2012-05-08  
我一直在纠结hibernate如何以扩展点的方式运行在felix中,但是一直找不到这种机制!楼主辛苦了,这篇文章让我茅塞顿开啊!只是对IPOJO了解很少,而且例子难找!不知可否发一份源码?感谢至极啊!icecream0211@gmail.com
2 楼 dengquanhao 2012-04-19  
楼主,这个是否可以提供bundle示例呢?不甚感激啊。邮箱:dengquanhao@163.com
1 楼 yusunnya 2012-03-21  
能把这3个bundle提供下载吗?  谢谢@!~~

相关推荐

    OSGI中Hibernate扩展在felix中的应用

    这通常涉及到创建OSGI bundles,每个bundle封装一个或多个Hibernate相关的类库,并正确声明它们的依赖关系。 以下是实现这一目标时可能涉及的关键知识点: 1. **OSGI Bundle**:OSGI的核心单元是bundle,它类似于...

    hibernate validate 中文文档 英文文档

    Hibernate是一个开源的对象关系映射(ORM)框架,它对JPA(Java持久性API)进行了实现,并提供了对象/关系映射工具以及Java数据库连接的封装。Hibernate Validator是Hibernate的子项目,它是一个校验框架,提供了在...

    Struts与Hibernate结合

    5.2.2 几个术语:如Locale、Resource Bundle等,Locale用于表示特定地区的语言环境,Resource Bundle存储特定语言的字符串资源。 5.2.3 Java中解决国际化问题:通过ResourceBundle类加载对应locale的资源文件,提供...

    关于Struts+Hibernate分页的例子

    对于分页的文本(如“上一页”、“下一页”等),可以使用Struts2的资源包(Resource Bundle)进行国际化处理,使应用更具通用性。 7. **测试和优化**: 完成以上步骤后,进行单元测试和集成测试,确保分页功能...

    内容管理系统(hibernate3+struts2+spring2)130224.zip

    8. **国际化与本地化**:可能使用Resource Bundle来支持多语言,为不同地区的用户提供合适的显示。 这个内容管理系统项目为学习者和开发者提供了一个实战平台,可以帮助他们深入了解和实践Java Web开发,尤其是在...

    OSGi进阶源代码

    2. **Struts Action Bundle**:这部分代码展示了如何将Struts Action打包成OSGi bundle,并声明所需的依赖,例如视图层(JSP)、模型层(业务对象)等。 3. **Spring配置**:Spring的XML配置文件可能被分割到各个...

    osgi进阶(中文)

    通过实例化的方法,读者可以理解如何把不同的功能封装在各自的bundle中,实现模块间的松散耦合。 3. 与流行Java B/S架构的集成 文档介绍了如何将OSGi技术与其他流行的Java技术栈集成,包括Hibernate、Spring和...

    新闻系统源码

    5. **国际化与本地化支持**:新闻系统可能还包含资源文件,如消息bundle,用于支持多语言环境。 6. **安全与权限管理**:对于用户登录和权限控制,可能使用了如Spring Security这样的框架来实现。 7. **日志记录**...

    hazelcast-spring-3.2.1.zip

    在开源项目标签下,这两个包都展示了 Java 社区如何通过封装和扩展现有技术,来满足特定的需求和场景,同时也为其他开发者提供了学习和借鉴的机会。在实际应用中,Hazelcast Spring 整合可以帮助构建可扩展的、高...

    struts1.x 常用知识详解

    1. **Resource Bundle**:Struts1.x支持多语言,通过Resource Bundle管理不同语言的文本资源。 2. **locale设置**:根据用户的选择或浏览器设置,Struts可以自动选择相应的本地化资源。 五、拦截器(Interceptor)...

    基于Struts的网上论坛BBS系统课程设计

    5. **国际化和本地化**:Struts支持多语言环境,通过资源包(Resource Bundle)可以实现页面内容的国际化和本地化。 6. **异常处理**:Struts提供了一套异常处理机制,可以定义全局的错误页面,当发生异常时,自动...

    struts项目

    在实际开发中,Struts可以与其他技术结合,如Hibernate(持久层框架)和Spring(依赖注入和企业级服务),形成Maven、Struts、Hibernate、Spring(MSSH)或Spring、Struts、Hibernate、iBatis(SSH或SSM)等流行的...

    struts 学习,吐血共享

    3. **Action和ActionForm**:编写自定义Action类来处理请求,以及ActionForm类来封装表单数据。 4. **JSP标签**:使用Struts提供的JSP标签库,如`&lt;html:form&gt;`、`*&gt;`和`*&gt;`,简化视图层的开发。 5. **ActionServlet*...

    基于Struts的商业网站网上交易评分系统

    4. **Tiles组件**:在Struts中,Tiles框架用于页面布局和组合,它可以将复杂的页面拆分成多个小的可重用组件,方便管理和维护。 5. **国际化与本地化**:Struts支持多语言环境,通过资源bundle文件实现动态加载不同...

    Jsp+Struts做的BBS系统

    JSP页面在服务器上被转换为Servlet,然后编译成Java字节码执行,实现了服务器端的业务逻辑处理。 1. **脚本元素**:用于编写Java代码,处理业务逻辑。 2. **表达式**:用于插入Java变量的值到输出流中。 3. **声明*...

    新闻文章NTsky新闻发布(提供JavaBean)v1.0-ntskynewsv1.0javabean

    这可能涉及到JDBC(Java Database Connectivity)或者ORM(对象关系映射)框架如Hibernate或MyBatis。通过这些技术,JavaBean可以直接映射到数据库中的表,实现数据的持久化存储。 5. **MVC模式**:在新闻发布系统...

    精通Struts:基于MVC的JavaWeb设计和开发(孙卫琴)pdf

    6. **国际化与本地化**:Struts支持多语言环境,通过资源包(Resource Bundle)实现页面的国际化,开发者可以为不同的地区提供相应的语言版本。 7. **异常处理**:Struts框架提供了全局的异常处理机制,通过配置...

    Java Struts Tutorial

    表单对象在Struts中用于封装请求参数,它与JSP页面上的表单元素相对应,帮助实现数据验证。 9. **Tiles框架集成** Tiles是Struts的一个插件,允许开发者创建和组合多个JSP页面,创建复杂的布局结构。 10. **异常...

Global site tag (gtag.js) - Google Analytics