`

osgi spring hibernate

阅读更多
 先来说说整合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();   
      
}   
       建一个用来初始化SessionFactory和事务管理的Bundle(wanged_core_persistent),由于使用Spring提供的LocalSessionFactoryBean会有问题,所以我单独写了两个类。
类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);   
            }   
        }   
    }   
}   
类LocalDataSourceConnectionProvider的代码:

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;   
    }   
   
}   
如果你对比其与Spring提供的同名类中的代码,相差不大。
下面来看看配置文件,我把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" />     
这里的引用 "实体注册" 服务需要在我们的实体Bundle中实现,现在已经搭好了架子,下一步就需要创建自己的实体Bundle和数据库操作的Bundle。由于这个Blog保存时经常保存不住,需要重写,所以我尽可能的将其划分开来写。 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics