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

Spring, Springmodules, JBPM持久化集成--优雅的背后(Part1)

    博客分类:
  • JBPM
阅读更多

Spring, Springmodules, JBPM持久化集成理解系列二 

 

【本系列如需转载,请注明作者及出处】 

 

本系列文章假设阅者具备以下知识:
1,ThreadLocal相关知识
2,Spring持久化,事务管理相关知识
3,Hibernate 持久化相关知识
4,Jbpm 持久化相关知识
5,Springmodules项目相关知识
6,相关J2EE知识


且具备以下材料:
1,Spring源代码
2,Hibernate源代码
3,Jbpm源代码
4,Springmodules源代码 

 

 

  本篇尝试探讨SpringModules集成的背后逻辑,这涉及到JbpmContext持久化的哲学。 

  JbpmContext持久化管理的哲学是,如果用户提供Context数据库连接,那么用户就要管理该数据库的打开与关闭。如果使用JbpmContext自己产生的持久化服务,那么该服务就要管理与持久化相关的操作。很像各人自扫门前雪,哪管他人瓦上霜。

 

 

这里首先引用Jbpm User Guide里面关于持久化的描述:
7.5. User provided stuff

You can also programmatically provide JDBC connections, hibernate sessions and hibernate session factories to jBPM.

When such a resource is provided to jBPM, it will use the provided resources rather then the configured ones.

The JbpmContext class contains some convenience methods to inject resources programmatically. For example, to provide a JDBC connectio to jBPM, use the following code:

JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
Connection connection = ...;
jbpmContext.setConnection(connection);

// invoke one or more persistence operations

} finally {
jbpmContext.close();
}

the JbpmContext class has following convenience methods for providing resource programmatically:

JbpmContext.setConnection(Connection);
JbpmContext.setSession(Session);
JbpmContext.setSessionFactory(SessionFactory);

 

 

 

上面的文字Jbpm就声明了它只管它自己的持久化逻辑,至于别人塞过来的,对不起,那是别人的事情。我想,很多人在看到Jbpm User guide的这些文字的时候,都会想弄明白藏在这些文字背后的逻辑的。  

  Jbpm中所有数据库操作的入口都是JbpmContext,各种的数据库操作例如saveJbpmContext都会委派给不同的xxxSession,例如GraphSessionTaskMgmtSession等来处理。

 

 

 

假设这个操作是loadTaskInstance,我将整个过程就缩小到我们关心的领域,一个是连接的打开,另外一个是连接的关闭:

 

 

 

第一部分,Session的打开:

 

 

【位置JbpmContext】

 
public TaskInstance loadTaskInstance(long taskInstanceId) {
    return getTaskMgmtSession().loadTaskInstance(taskInstanceId);
}

public TaskMgmtSession getTaskMgmtSession() {
    PersistenceService persistenceService = getPersistenceService();
    if (persistenceService==null) return null;
    return (persistenceService!=null ? persistenceService.getTaskMgmtSession() : null);

 

 
 

这个PersistenceService就是jbpm.cfg.xml里面配置的org.jbpm.persistence.db.DbPersistenceService了,在上面getTaskMgmtSession这个方面里面PersistenceService就返回了一个带有一个Hibernate session的TaskMgmtSession了。

如下所示:

 

【位置DbPersistenceService】

 

public TaskMgmtSession getTaskMgmtSession() {
    if (taskMgmtSession==null) {
      Session session = getSession();
      if (session!=null) {
        taskMgmtSession = new TaskMgmtSession(session);
      }
    }
    return taskMgmtSession;
  }

 

好了,到此我们就差不多达到Jbpm管理Session的环节了,我们再进入到getSession方法,看看它到底做了什么事情:

 

 

准备工作:1以下是会涉及的布尔变量,以及其默认值:

 

【位置DbPersistenceService】

 

Connection connection = null;
  boolean mustConnectionBeClosed = false;

  Transaction transaction = null;
  boolean isTransactionEnabled = true;
  boolean isCurrentSessionEnabled = false;
  boolean isRollbackOnly = false;

  Session session;
  boolean mustSessionBeFlushed = false;
boolean mustSessionBeClosed = false;

 

 

 

准备工作2由于DbPersistenceService只有一个Constructor,也就是

 

【位置DbPersistenceService】

 

public DbPersistenceService(DbPersistenceServiceFactory persistenceServiceFactory) {
    this.persistenceServiceFactory = persistenceServiceFactory;
    this.isTransactionEnabled = persistenceServiceFactory.isTransactionEnabled();
    this.isCurrentSessionEnabled = persistenceServiceFactory.isCurrentSessionEnabled();
  }

 

 

  在这里我们就知道了,进行数据库操作所用到SessionSessionFactory就只能通过相关的SetterGetter方法来取到了。  现在进入这个方法:

 

【位置DbPersistenceService】

public Session getSession() {
    if ( (session==null)
         && (getSessionFactory()!=null) 
       ) {
      Connection connection = getConnection(false); 
      if (isCurrentSessionEnabled) {
        session = getSessionFactory().getCurrentSession();
        mustSessionBeClosed = false;
        mustSessionBeFlushed = false;
        mustConnectionBeClosed = false;
      } else if (connection!=null) {
        log.debug("creating hibernate session with connection "+connection);
        session = getSessionFactory().openSession(connection);
        mustSessionBeClosed = true;
        mustSessionBeFlushed = true;
        mustConnectionBeClosed = false;
      } else {
        log.debug("creating hibernate session");
        session = getSessionFactory().openSession();
        mustSessionBeClosed = true;
        mustSessionBeFlushed = true;
        mustConnectionBeClosed = false;
      }
      
      if (isTransactionEnabled) {
        log.debug("beginning hibernate transaction");
        transaction = session.beginTransaction();
      }
    }
    return session;
  }

  

 

 

 

 

 

 

因为注入到JbpmContextsessionsessionFactory Setter方法都是将其注入到persistenceService里面的 在上面这个方法里

1)如果用户向JbpmContext提供了Session,那么会立刻返回该session,并且不会修改mustConnectionBeClosedmustSessionBeClosed等的值。

2)如果用户向JbpmContext提供了SessionFactory,在getConnection时将mustConnectionBeClosed设置成了false,另外使用返回的Connection创建了一个Hibernate Session,即session = getSessionFactory().openSession(connection);紧接着将mustSessionBeClosedmustSessionBeFlushed设置成了true

 

 

3
0
分享到:
评论
1 楼 huchao176 2009-03-12  
     

相关推荐

Global site tag (gtag.js) - Google Analytics