为什么要封装?
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);
}
}
分享到:
相关推荐
基于Hibernate O / R持久性框架的资源包实现。
hibernate-tools.jar
平台依赖度低的解决方案 ...测试环境:equinox3.5.2。其它用到的Bundle包括hibernate、hibernate-annotation、hsqldb、 spring、spring-osgi等。请到http://www.springsource.com/repository/下载。
Laya 用TypeScript写的代码,编译成JavaScript后bundle.js没更新
Intent_Bundle_传参数
Android中用来在Activity之间传递数据可以用Bundle,这是一个在两个Bundle间用Bundle传递数据和接收数据的小例子
Bundle Manager是基于Asset Bundle的动态加载方案。让开发者可以在不编写任何代码的情况下,方便地创建,修改,优化Asset Bundle。 特点: - 不用编写bundle管理代码。 创建和修改bundle都不需要再做繁杂的硬编码。...
matlab开发-BundleAdjustment。解束平差(共线方程)摄影测量的一个简单函数
Jar转换为Bundle工具,需要的可以下载
NULL 博文链接:https://skyteam.iteye.com/blog/1896973
Android 通过Intent使用Bundle传递对象 Android开发中有时需要在应用中或进程间传递对象,下面详细介绍Intent使用Bundle传递对象的方法。 被传递的对象需要先实现序列化,而序列化对象有两种方式:java.io....
包含Bundle两种传递数据方式,一种是传递简单数据,另一种是传递自定义数据
swiper-bundle.min.js
Laya 用TypeScript写的代码,编译成JavaScript后bundle.js没更新问题的原因追寻
TheLastGhost's Bundle
bundle adjustment tri
android activity bundle 通信示例
通过编辑器扩展实现打AssetsBundle资源包
Android应用源码之Bundle_Bundle
Bundle是将数据传递到另一个上下文中或保存或回复你自己状态的数据存储方式