Spring+Hibernate实现动态SessionFactory切换(改进版)

发现存在一些问题:

需要配置多个HibernateTransactionManager和多个Spring切面

这样带来两个问题

1.程序效率降低,因为Spring进行多次Advice的拦截

2.如果其中一个SessionFactory连接出现问题,会导致整个系统无法工作

今天研究出一种新的方法来解决此类问题

1. 数据源及Hibernate SessionFactory配置:
import
 org.hibernate.SessionFactory;  



  


public
 
interface
 DynamicSessionFactoryInf 
extends
 SessionFactory {  



  


    public
 SessionFactory getHibernateSessionFactory();  



}  

3. 定义DynamicSessionFactory实现DynamicSessionFactoryInf

public
 
class
 DynamicSessionFactory 
implements
 DynamicSessionFactoryInf ,ApplicationContextAware{  



      


    private
 
static
 
final
 
long
 serialVersionUID = 1L;  



  


    private
 ApplicationContext applicationContext;  



    //动态调用SessionFactory
  



    private
 SessionFactory getHibernateSessionFactory(String name) {  



        return
 (SessionFactory) applicationContext.getBean(name);  



    }  


        //实现DynamicSessionFactoryInf 接口的方法
  



    public
 SessionFactory getHibernateSessionFactory() {  



        return
 getHibernateSessionFactory(ThreadLocalUtil.getCurrentITAsset()  



                .getSessionFactoryName());  


    }  


      


       //以下是实现SessionFactory接口的方法,并对当前的SessionFactory实体进行代理
  



    public
 Reference getReference() 
throws
 NamingException {  



        return
 getHibernateSessionFactory().getReference();  



    }  


  


      


  


    public
 Session openSession() 
throws
 HibernateException {  



        return
 getHibernateSessionFactory().openSession();  



    }  


  


    public
 Session openSession(Interceptor interceptor)  



            throws
 HibernateException {  



        return
 getHibernateSessionFactory().openSession(interceptor);  



    }  


  


    public
 Session openSession(Connection connection) {  



        return
 getHibernateSessionFactory().openSession(connection);  



    }  


  


    public
 Session openSession(Connection connection, Interceptor interceptor) {  



        return
 getHibernateSessionFactory().openSession(connection,interceptor);  



    }  


  


    public
 Session getCurrentSession() 
throws
 HibernateException {  



        return
 getHibernateSessionFactory().getCurrentSession();  



    }  


  


    public
 StatelessSession openStatelessSession() {  



        return
 getHibernateSessionFactory().openStatelessSession();  



    }  


  


    public
 StatelessSession openStatelessSession(Connection connection) {  



        return
 getHibernateSessionFactory().openStatelessSession(connection);  



    }  


  


    public
 ClassMetadata getClassMetadata(Class entityClass) {  



        return
 getHibernateSessionFactory().getClassMetadata(entityClass);  



    }  


  


    public
 ClassMetadata getClassMetadata(String entityName) {  



        return
 getHibernateSessionFactory().getClassMetadata(entityName);  



    }  


  


    public
 CollectionMetadata getCollectionMetadata(String roleName) {  



        return
 getHibernateSessionFactory().getCollectionMetadata(roleName);  



    }  


  


    public
 Map getAllClassMetadata() {  



        return
 getHibernateSessionFactory().getAllClassMetadata();  



    }  


  


    public
 Map getAllCollectionMetadata() {  



        return
 getHibernateSessionFactory().getAllCollectionMetadata();  



    }  


  


    public
 Statistics getStatistics() {  



        return
 getHibernateSessionFactory().getStatistics();  



    }  


  


    public
 
void
 close() 
throws
 HibernateException {  



        getHibernateSessionFactory().close();  


    }  


  


    public
 
boolean
 isClosed() {  



        return
 getHibernateSessionFactory().isClosed();  



    }  


  


    public
 Cache getCache() {  



        return
 getHibernateSessionFactory().getCache();  



    }  


  


    public
 
void
 evict(Class persistentClass) 
throws
 HibernateException {  



        getHibernateSessionFactory().evict(persistentClass);  


    }  


  


    public
 
void
 evict(Class persistentClass, Serializable id)  



            throws
 HibernateException {  



        getHibernateSessionFactory().evict(persistentClass, id);  


    }  


  


    public
 
void
 evictEntity(String entityName) 
throws
 HibernateException {  



        getHibernateSessionFactory().evictEntity(entityName);  


    }  


  


    public
 
void
 evictEntity(String entityName, Serializable id)  



            throws
 HibernateException {  



        getHibernateSessionFactory().evictEntity(entityName, id);  


    }  


  


    public
 
void
 evictCollection(String roleName) 
throws
 HibernateException {  



        getHibernateSessionFactory().evictCollection(roleName);  


    }  


  


    public
 
void
 evictCollection(String roleName, Serializable id)  



            throws
 HibernateException {  



        getHibernateSessionFactory().evictCollection(roleName, id);  


    }  


  


    public
 
void
 evictQueries(String cacheRegion) 
throws
 HibernateException {  



        getHibernateSessionFactory().evictQueries(cacheRegion);  


    }  


  


    public
 
void
 evictQueries() 
throws
 HibernateException {  



        getHibernateSessionFactory().evictQueries();  


    }  


  


    public
 Set getDefinedFilterNames() {  



        return
 getHibernateSessionFactory().getDefinedFilterNames();  



    }  


  


    public
 FilterDefinition getFilterDefinition(String filterName)  



            throws
 HibernateException {  



        return
 getHibernateSessionFactory().getFilterDefinition(filterName);  



    }  


  


    public
 
boolean
 containsFetchProfileDefinition(String name) {  



        return
 getHibernateSessionFactory().containsFetchProfileDefinition(name);  



    }  


  


    @Override
  



    public
 
void
 setApplicationContext(ApplicationContext applicationContext)  



            throws
 BeansException {  



        this
.applicationContext = applicationContext;  



    }  


  


      


  


}  

4. 配置动态SessionFactory

public
 
class
 DynamicTransactionManager 
extends
 HibernateTransactionManager {  



  


    private
 
static
 
final
 
long
 serialVersionUID = 1047039346475978451L;  



    //重写getDataSource方法,实现动态获取
  



    public
 DataSource getDataSource() {  



        DataSource sfds = SessionFactoryUtils.getDataSource(getSessionFactory());  


        return
 sfds;  



    }  


       //重写getSessionFactory方法,实现动态获取SessionFactory
  



    public
 SessionFactory getSessionFactory() {  



        DynamicSessionFactoryInf dynamicSessionFactory = (DynamicSessionFactoryInf) super
  



                .getSessionFactory();  


        SessionFactory hibernateSessionFactory = dynamicSessionFactory  


                .getHibernateSessionFactory();  


        return
 hibernateSessionFactory;  



    }  


    //重写afterPropertiesSet,跳过数据源的初始化等操作
  



    public
 
void
 afterPropertiesSet() {  



        return
;  



    }  


  


}  

6. 配置dynamicTransactionManager

<bean id="dynamicTransactionManager"
		class="com.hp.it.qdpadmin.common.DynamicTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"/>
</bean>

7. 为SessionFactory配置事务切面

<tx:advice id="dynamicTxAdvice" transaction-manager="dynamicTransactionManager">  
        <tx:attributes>  
            <tx:method name="get*" read-only="true" />  
            <tx:method name="find*" read-only="true" />  
            <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />  
        </tx:attributes>  
    </tx:advice>  
      
      
    <aop:config proxy-target-class="true">    
        <aop:pointcut id="txPointcut" expression="execution(* com.service.*.*(..))"/>          
        <aop:advisor advice-ref="dynamicTxAdvice" pointcut-ref="txPointcut" /> 
    </aop:config>