查询了很多网上的帖子,主流的整合方式大体为4种。前两种不必说了,没什么扩展性,不予考虑。第三种采用Eclipse-RegisterBuddy方式(官方的整合方式)和第四种则采用Eclipse插件的扩展点,这样种都不能脱离Equinox实现,最后还是决定用自己的一套方式。
先来说说整合Hibernate的关键之处。其实用OSGi整合Hibernate很简单,但要通过Bundle方式做到可以扩展新的持久化层面的东西(比如添加新的表和操作)就比较费事了。因为Hibernate在初始化时根据注册的实体类创建SessionFactory,这样当有新的实体类添加进来时就要创建新的SessionFactory,这样系统中出现两个甚至多个SessionFatory会导致一系列的问题。显然整合Hibernate关键就是解决实体类注册与SessionFactory创建的问题。
我的具体思路如下。
首先将Hibernate单独多为一个Bundle(wanged_commons_hibernate)以便提供其他Bundle所需类包。
然后建立一个用于提供实体注册接口的Bundle(wanged_core_persistent_entity_register),代码如下:
建一个用来初始化SessionFactory和事务管理的Bundle(wanged_core_persistent),由于使用Spring提供的LocalSessionFactoryBean会有问题,所以我单独写了两个类。
类LocalSessionFactoryBean的代码:
类LocalDataSourceConnectionProvider的代码:
如果你对比其与Spring提供的同名类中的代码,相差不大。
下面来看看配置文件,我把Bean的初始化放在bean.xml中:
而服务与引用的声明放在osgi-service.xml中:
这里的引用 "实体注册" 服务需要在我们的实体Bundle中实现,现在已经搭好了架子,下一步就需要创建自己的实体Bundle和数据库操作的Bundle。由于这个Blog保存时经常保存不住,需要重写,所以我尽可能的将其划分开来写。
先来说说整合Hibernate的关键之处。其实用OSGi整合Hibernate很简单,但要通过Bundle方式做到可以扩展新的持久化层面的东西(比如添加新的表和操作)就比较费事了。因为Hibernate在初始化时根据注册的实体类创建SessionFactory,这样当有新的实体类添加进来时就要创建新的SessionFactory,这样系统中出现两个甚至多个SessionFatory会导致一系列的问题。显然整合Hibernate关键就是解决实体类注册与SessionFactory创建的问题。
我的具体思路如下。
首先将Hibernate单独多为一个Bundle(wanged_commons_hibernate)以便提供其他Bundle所需类包。
然后建立一个用于提供实体注册接口的Bundle(wanged_core_persistent_entity_register),代码如下:
java 代码
- package wanged.core.persistent.entity;
- @SuppressWarnings("unchecked")
- public interface EntityRegister {
- /**
- * 注册Hibernate的实体Class
- * @return
- */
- Class[] register();
- }
类LocalSessionFactoryBean的代码:
java 代码
- package wanged.core.persistent;
- import java.util.HashMap;
- import java.util.Properties;
- import javax.sql.DataSource;
- import org.hibernate.ConnectionReleaseMode;
- import org.hibernate.HibernateException;
- import org.hibernate.SessionFactory;
- import org.hibernate.cfg.Configuration;
- import org.hibernate.cfg.Environment;
- import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
- import org.springframework.orm.hibernate3.AbstractSessionFactoryBean;
- import org.springframework.orm.hibernate3.SpringSessionContext;
- import org.springframework.orm.hibernate3.TransactionAwareDataSourceConnectionProvider;
- import wanged.core.persistent.entity.EntityRegister;
- @SuppressWarnings("unchecked")
- public class LocalSessionFactoryBean extends AbstractSessionFactoryBean {
- private static final ThreadLocal configTimeDataSourceHolder = new ThreadLocal();
- private Properties hibernateProperties;
- private HashMapnew HashMap
- private Configuration configuration;
- public static DataSource getConfigTimeDataSource() {
- return (DataSource) configTimeDataSourceHolder.get();
- }
- /**
- * 注册Entity的Class数组
- *
- * @param er
- */
- @SuppressWarnings("unchecked")
- public void setEntityRegister(EntityRegister[] erArr) {
- for (EntityRegister er : erArr) {
- this.addEntityRegister(er);
- }
- }
- @SuppressWarnings("unchecked")
- public void setEntityRegister(EntityRegister er) {
- this.addEntityRegister(er);
- }
- private void addEntityRegister(EntityRegister er){
- // TODO:对registerClass()中取得的数组进行验证
- this.entityClasses.put(er, er.register());
- }
- /**
- * 卸载Entity的Class数组
- *
- * @param er
- */
- public void unsetEntityRegister(EntityRegister er) {
- this.entityClasses.remove(er);
- // TODO:重新初始化SessionFactory
- }
- public void setHibernateProperties(Properties hibernateProperties) {
- this.hibernateProperties = hibernateProperties;
- }
- public Properties getHibernateProperties() {
- if (this.hibernateProperties == null) {
- this.hibernateProperties = new Properties();
- }
- return this.hibernateProperties;
- }
- @SuppressWarnings("unchecked")
- protected SessionFactory buildSessionFactory() {
- Configuration config = new Configuration();
- DataSource dataSource = getDataSource();
- if (dataSource != null) {
- configTimeDataSourceHolder.set(dataSource);
- }
- try {
- config.setProperty(Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString());
- if (isExposeTransactionAwareSessionFactory()) {
- config.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName());
- }
- if (this.hibernateProperties != null) {
- config.addProperties(this.hibernateProperties);
- }
- if (dataSource != null) {
- boolean actuallyTransactionAware = (isUseTransactionAwareDataSource() || dataSource instanceof TransactionAwareDataSourceProxy);
- config.setProperty(Environment.CONNECTION_PROVIDER, actuallyTransactionAware ? TransactionAwareDataSourceConnectionProvider.class
- .getName() : LocalDataSourceConnectionProvider.class.getName());
- }
- // 添加Entity的类
- for (Class[] cArr : this.entityClasses.values()) {
- for (Class c : cArr) {
- config.addClass(c);
- }
- }
- this.configuration = config;
- return config.buildSessionFactory();
- } finally {
- if (dataSource != null) {
- configTimeDataSourceHolder.set(null);
- }
- }
- }
- /**
- * Return the Configuration object used to build the SessionFactory. Allows
- * access to configuration metadata stored there (rarely needed).
- *
- * @throws IllegalStateException
- * if the Configuration object has not been initialized yet
- */
- public final Configuration getConfiguration() {
- if (this.configuration == null) {
- throw new IllegalStateException("Configuration not initialized yet");
- }
- return this.configuration;
- }
- public void destroy() throws HibernateException {
- DataSource dataSource = getDataSource();
- if (dataSource != null) {
- configTimeDataSourceHolder.set(dataSource);
- }
- try {
- super.destroy();
- } finally {
- if (dataSource != null) {
- configTimeDataSourceHolder.set(null);
- }
- }
- }
- }
java 代码
- package wanged.core.persistent;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.util.Properties;
- import javax.sql.DataSource;
- import org.hibernate.HibernateException;
- import org.hibernate.connection.ConnectionProvider;
- import org.hibernate.util.JDBCExceptionReporter;
- public class LocalDataSourceConnectionProvider implements ConnectionProvider {
- private DataSource dataSource;
- private DataSource dataSourceToUse;
- public void configure(Properties props) throws HibernateException {
- this.dataSource = LocalSessionFactoryBean.getConfigTimeDataSource();
- if (this.dataSource == null) {
- throw new HibernateException("No local DataSource found for configuration - " +
- "dataSource property must be set on LocalSessionFactoryBean");
- }
- this.dataSourceToUse = getDataSourceToUse(this.dataSource);
- }
- protected DataSource getDataSourceToUse(DataSource originalDataSource) {
- return originalDataSource;
- }
- public DataSource getDataSource() {
- return dataSource;
- }
- public Connection getConnection() throws SQLException {
- try {
- return this.dataSourceToUse.getConnection();
- }
- catch (SQLException ex) {
- JDBCExceptionReporter.logExceptions(ex);
- throw ex;
- }
- }
- public void closeConnection(Connection con) throws SQLException {
- try {
- con.close();
- }
- catch (SQLException ex) {
- JDBCExceptionReporter.logExceptions(ex);
- throw ex;
- }
- }
- public void close() {
- }
- public boolean supportsAggressiveRelease() {
- return false;
- }
- }
下面来看看配置文件,我把Bean的初始化放在bean.xml中:
xml 代码
- <!-- 本地调试使用连接池-->
- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
- <property name="driverClassName" value="org.gjt.mm.mysql.Driver" />
- <property name="url" value="jdbc:mysql://localhost:3306/cms" />
- <property name="username" value="root" />
- <property name="password" value="root" />
- <property name="connectionProperties">
- <props>
- <prop key="useUnicode">true</prop>
- <prop key="characterEncoding">GBK</prop>
- </props>
- </property>
- </bean>
- <!-- 服务实现类定义 -->
- <bean id="sessionFactory" class="wanged.core.persistent.LocalSessionFactoryBean">
- <property name="hibernateProperties">
- <props>
- <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
- <prop key="hibernate.show_sql">false</prop>
- <prop key="hibernate.cache.use_query_cache">true</prop>
- <prop key="hibernate.jdbc.batch_size">20</prop>
- </props>
- </property>
- <property name="dataSource" ref="dataSource" />
- <property name="entityRegister" ref="entityRegister" />
- </bean>
- <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory" ref="sessionFactory" />
- </bean>
而服务与引用的声明放在osgi-service.xml中:
xml 代码
- <osgi:reference id="entityRegister" interface="wanged.core.persistent.entity.EntityRegister" cardinality="1..n"/>
- <osgi:service interface="org.hibernate.SessionFactory" ref="sessionFactory" />
- <osgi:service interface="org.springframework.transaction.PlatformTransactionManager" ref="txManager" />
本文介绍了一种在OSGi环境中整合Hibernate的方法,通过自定义的Bundle实现了实体类的动态注册与SessionFactory的灵活管理。
160

被折叠的 条评论
为什么被折叠?



