`
lzh166
  • 浏览: 298555 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

如何在jbpm的handler中能够使用由spring管理的bean对象呢?

    博客分类:
  • JBPM
阅读更多
如何在jbpm的handler中能够使用由spring管理的bean对象呢?
首先先来理解spring中对JavaBean的管理机制。Spring容器所管理的bean对象都是由beanFacotry工厂来实例化,所以要使用pring容器中bean实例对象,必须该类也是由spring容器所管理,否则无法从bean工厂中得到bean实例对象。
理解了上面的简单阐述之后,下面我来看看在jbpm中是如何访问spring容器中的bean对象的
在一个将jbpm集成到ssh架构中项目中,要想在一个由jbpm所管理的java类中访问spring容器中javabean,如何访问呢?
Struts 最新版本中是由

我们先抛开struts2专门来看spring,那么我们就从spring标准配置文件来说起,如果你要向某个由spring管理的对象中注入一个对象,我们该如何去做呢?举例说明:如果由两个对象A、B,现在需要在B对象中使用A对象,那么我们通过什么方式将A注入到B中去呢?首先A、B两个对象都必须是由spring容器来管理,那么我们就需要在配置文件定义property 属性来注入,现在A、B都有spring容器来管理的,那么我如何得到其中A对象呢?因为AB对象都是由spring容器来创建的,所以要想得到A对象,就首先得到BeanFactory--->GetA(),然后才能拿到A,这时A指向B对象的引用才有值,才能把A注入到B中。
理解了上面的spring管理机制后,下面我们就来讨论如何在jbpm的handler中访问由spring管理的bean对象呢?
1、 第一种不推荐的方式:
在spring配置文件中配置如下:
<bean id="roleAssignmentHandler03" class="com.oa.service.handler.RoleAssignmentHandler03">
		<property name="userService" ref="userService" />
	</bean>

定义一个类变量(静态的static,这个类的所有实例共享的变量),启动服务器时,初始化spring时就创建了BeanFactory,在创建BeanFacotry时,就实例化了所有对象。也就说也就创建了一个roleAssignmentHandler03 对象,放到了它自己容器的那块内存中,这个对象拥有一个指向userService的引用,因为我在这里定义的是类变量。等下次在创建这个对象时,在这个类变量中同样是有值。但是这种方法并不推荐,这种方式有点浪费内存空间,spring已经给我们创建了对象,但是我们并没有去使用它。
public class RoleAssignmentHandler03 implements AssignmentHandler {
private static UserService userService;
	
	public void setUserService(UserService  _userService) {
		userService = _userService;
	}
……	

2、 第二种不推荐的方式:
Pring它是个容器,同样它是个Bean工厂,如果我们spring看成个bean工厂的话,那么我就可以从BeanFactory中得到我们的bean对象,那么如何去得到BeanFactory对象呢?
我不能向往常做测试那样通过new ClassPathXmlApplicationContext("");来创建它,我们需要从当前环境中去拿,那么从什么地方去拿呢?那么就得明白它是如何创建的,由谁来创建并管理的?在服务器启动时,它就会初始化web.xml中的linstener配置信息,创建一个Bean’Factroy对象,并把这个对象放到了ServletContext中,我们可以利用spring中的一个工具类来得到ServletContext中的BeanFactory对象,但是并推荐,因为ServletActionContext是Struts中的,在业务逻辑中过分依赖于展现层的内容,JBPM是不依赖于展现层内容的,也不推荐于依赖关系的存在。
BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletActionContext.getServletContext());
		
		UserService userService = factory.getBean("userService");

3、 第三种并不推荐的方式
在项目开发中采用SSH与JBPM集成时,用到了一个第三方的集成包,我们可以从这里得到解决方案,(采用jbpm3.1所以其第三方集成包为spring-modules-jbpm31.jar)在其文档(jbpm31.html)中可以了解到,采用如下配置:
流程定义文件配置
<assignment class="com.oa.service.handler.RoleAssignmentHandler03">
      	  	  <targetBean>roleAssignmentHandler03</targetBean>
</assignment>

在spring配置文件中可以这样定义如下
<bean id="roleAssignmentHandler03" class="com.oa.service.handler.RoleAssignmentHandler03">
		<property name="userService" ref="userService" />
		<property name="roleName" value="系统管理员"/>
	</bean>

但这是种方法并不是很灵活,有些东西已经写死在配置文件中了,所以我们并推荐此方式,那么我们如何来得到一个好的解决方案呢?
4、 第四种方式:
回过头来,我们接着继续思考从BeanFactory中去获得,流程定义文件并不去修改它,这样就不会破坏它的灵活性,那么接下来要分析的问题就是如何来获得BeanFactory呢?那就得深入了解一下spring,现在来看一个问题:在一个单例中如何获得一个非单例的对象呢?也就是将B注入到A中   A是单例,但是B不是单例,直接采用Resource或在配置文件利用property注入的话,是无法实现的,只能将B变成一个单例对象来使用。那么我们在单例对象中如何动态获取依赖对象呢?有一种方式就从它的BeanFactory中去获得其对象,如何在由spring管理的对象中拿到BeanFactory呢?也就是说在容器实例对象中访问容器本身,在spring中有这样一个BeanFactoryAware接口,在这个接口有个setBeanFactory(BeanFactory f)方法,我们可以实现该接口,重写这个方法,来得到我们BeanFactory,从中得到动态的得到BeanFactory中实例对象,但是放到jbpm中handler类中来使用,还是无法实现的,因为在这里它不是有spring来管理的,所以即使实现BeanFactory接口,重写其方法,但是无法将BeanFactory设置上值的,因为它是由spring来管理的,所以我无法从一个不是spring所管理的bean中去注入spring所提供的bean对象。但是我们可以通过另一种途径来解决这个问题:创建一个辅助类BeanFactroyHelper类,让它来实现刚才这个BeanFactoryAware接口,具体如下:
public class BeanFactoryHelper implements BeanFactoryAware {

	private static BeanFactory factory;
	
	public void setBeanFactory(BeanFactory f) throws BeansException {
		
		factory = f;
	}
	
	public static  BeanFactory getFactory(){
		return factory;
	}

}

然后,让上面这个类纳入spring的管理,在spring中配置如下:
<bean id="beanFactoryHelper" class="com.oa.service.handler.BeanFactoryHelper">
	</bean>

最后在我们handler类中,直接使用就可以了
BeanFactory factory = BeanFactoryHelper.getFactory();

这种方式可以,但是我并采用这种方式,因为第四种方式已经有人给我做了。所以我们就不需要在重复做这些类似的工作了。所以这种方式我也不会采用。
5、 第五种方式:
通过上面所说的方式,在spring-modules.jar这个第三方集成包开发人中已经采用类似的方式实现了。那么他们是如何实现的呢?这就需要来了解一下jbpmHandlerProxy的基本原理,在JbpmHandlerProxy类中实现了ActionHandler, AssignmentHandler, DecisionHandler, TaskControllerHandler等接口,在实现不同的接口会调用不同它的不同的方法execute、assign、decide…
ServiceLocator,在spring中也提供了一个ServiceLocator这种设计模式的一个接口BeanFactoryLocator、 BeanFactoryReference接口,要想详细了解其内部机制需要我们进一步花费精力去解析其源码了。(在这里就不详细去分析了)这里我只是了解jbpmFactoryPorxy类中实现机制的大体思想,所以下面我就针对在代理类中的具体实现思想大体说一下:在JbpmHandlerProxy类中得到BeanFactory对象,主要是通过JbpmFactoryLocator来得到BeanFactoryReference,通过BeanFactoryReference来得到Factory。那么在JbpmHandlerProxy类中的JbpmFactoryLocator是从哪里得到的呢?查看源码可以得知在其JbpmFactoryLocator类下有个setBeanFactory()方法,那么这个方法是有谁调用的呢?通过查看得知是LocalJbpmConfigurationFactoryBean类来调用的。主要分析图如下:


以上就jbpmFactoryProxy中内部机制。
下面我就来说一下具体解决方案是:
首先通过利用jbpmFactoryProxy的实现类中retrieveBeanFactory方法的具体实现方式,来得到jbpm中已经注入的BeanFactory对象,下面我将进一步进行封装来实现自动注入的功能。
先贴出在jbpm的handler类中的具体使用,和在spring中使用Bean对象一样使用。
/**
	 * 是由BaseAutowire自动注入
	 */
	@Resource
	private UserService userServce;


下面一段代码将是所抽取出来的基类:
/**
 * 自动注入BeanFactory基类
 * @author lzh
 *
 */
public class BaseAutowire {
	
	/**
	 * 在调用子类的时会自动调用
	 * 在构造方法中调用retrieveBeanFactory()方法得到BeanFactory对象
	 * 利用它的实现接口设置将该自身设置为自动注入到子类中
	 */
	public BaseAutowire() {
		((AutowireCapableBeanFactory)retrieveBeanFactory())
		.autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
	}

	protected BeanFactory retrieveBeanFactory() {
		BeanFactoryLocator factoryLocator = new JbpmFactoryLocator();
		BeanFactoryReference factory = factoryLocator.useBeanFactory(null);
		if (factory == null)
			throw new IllegalArgumentException("no beanFactory found under key=" + null);

		try {
			return factory.getFactory();
		}
		finally {
			factory.release();
		}
	}

}

以上是我在学习jbpm时所记录下,希望能够对今后的工作起到一定作用。
  • 大小: 24.2 KB
分享到:
评论

相关推荐

    jbpm4整合struts2+spring2.5+hibernate3.3

    在Spring中配置jbpm4,主要涉及以下几点: 1. 配置jbpm的数据源,使其与Hibernate共用,以确保事务的一致性。 2. 注册jbpm的SessionFactory,使Spring能够管理SessionFactory的生命周期。 3. 配置jbpm的JobExecutor...

    jbpm4.3与spring整合

    在企业级应用开发中,流程管理引擎JBPM(JBoss Business Process Management)与Spring框架的结合使用是常见的一种技术方案。JBPM是一个灵活、强大的业务流程管理工具,而Spring框架则以其优秀的依赖注入(DI)和...

    jbpm+spring配置

    1. **引入依赖**:首先,要在Spring应用中使用jbpm,你需要在项目中引入jbpm的相关库,包括jbpm的jar包和Spring对jbpm的支持库。这通常通过Maven或Gradle的依赖管理来实现。 2. **配置jbpm数据源**:jbpm需要一个...

    jbpm4 集成 spring 的试用代码

    在Spring中,我们可以使用`jbpmDeployer` bean来部署这些流程定义文件。 3. **任务服务**:集成后,我们可以通过Spring的`JbpmTaskService`来操作任务,例如查询任务、领取任务、完成任务等。 4. **流程实例管理**...

    jBPM4与Spring整合的2种方式

    1. **事务边界**:在Spring中,确保jBPM4的操作与数据库操作处于同一事务范围内,以保证数据一致性。 2. **日志和异常处理**:利用Spring的日志管理和AOP切面,对jBPM4的异常进行统一处理,提高系统的健壮性。 3. **...

    JBPM4.3 Spring会签 实例

    首先,我们需要在Spring配置文件中定义JBPM的相关bean,包括流程引擎、工作内存、流程定义仓库等。这些bean是Spring与JBPM交互的基础,通过它们可以启动流程实例、执行任务以及查询流程状态。 其次,创建流程定义...

    spring2_struts2_jbpm3.2.rar_jbpm struts2_jbpm-demo_jbpm3 spring_

    在Spring中,我们可以创建一个Service Bean来调用JBPM的工作流API,处理流程的启动、暂停、继续和结束等操作。同时,Struts2的动作类可以通过Spring的代理访问这些Service Bean,从而在用户交互时触发流程的执行。...

    JBPM使用实例,sql spring

    2. **项目源代码(全,不含jar包).rar**:这可能是一个完整的JBPM项目源代码,包含了流程定义、服务实现、配置文件等,用于展示如何在实际项目中使用JBPM和Spring进行流程管理。 3. **sql.rar**:这个压缩包可能...

    Jbpm4.4+hibernate3.5.4+spring3.0.4+struts2.1.8整合

    【JBPM4.4+Hibernate3.5.4+Spring3.0.4+Struts2.1.8整合】的整个过程涉及到多个关键组件的集成,这些组件都是Java企业级开发中的重要部分。首先,JBPM(Business Process Management)是一个开源的工作流引擎,它...

    jbpm5.4 spring mvc 集成

    - **jbpm配置**:需要在Spring配置文件中定义jbpm的数据源、事务管理器、流程引擎工厂等bean。 - **Spring MVC配置**:配置DispatcherServlet、视图解析器、模型-视图映射等,同时设置jbpm相关bean的事务属性。 -...

    spring与JBPM整合ppt

    标题中的“spring与JBPM整合ppt”指的是将Spring框架与JBPM(Business Process Management,业务流程管理)系统相结合,以实现更加高效、灵活的企业级应用流程管理。在本PPT中,我们预计会探讨以下几个核心知识点: ...

    Jbpm4.4 整合Spring Hibernate4

    在Jbpm4.4中整合Spring,可以利用Spring的这些优势,比如将Jbpm的流程实例管理、任务分配等操作集成到Spring容器中,实现流程服务的声明式配置和管理。 **3. Hibernate4整合** Hibernate4是流行的ORM(对象关系映射...

    jbpm4.0.0alpha2整合到spring

    在Spring中,可以通过声明bean来实现这些接口,然后通过@Autowired注解自动注入,以便在业务代码中使用。 5. **任务监听器与事件处理**:Spring允许我们自定义监听器来响应Jbpm中的特定事件,如任务分配、流程启动...

    Spring与JBPM4的集成.docx

    Dependency Lookup是指在JBPM4中使用Spring框架来管理依赖关系的机制,Transaction Management是指JBPM4中的事务管理机制,Activity是指JBPM4中的活动管理机制。这些机制的集成可以提供更加灵活和高效的业务流程管理...

    JBPM4.4+spring+ext整合

    Spring框架则是Java开发中的核心组件,用于依赖注入和管理bean,它在企业级应用中广泛使用。EXT是基于JavaScript的UI库,主要用于创建富客户端应用程序。当将这三者结合在一起时,可以构建出功能强大且用户友好的...

    jbpm4.0+ext3.0+spring+hibernate整合实例

    在本例中,Spring可能被用来管理jbpm、hibernate以及EXTJS的bean,实现组件间的解耦。 **Hibernate** Hibernate是一个流行的Java ORM(Object-Relational Mapping)框架,用于简化数据库操作。它允许开发者用Java...

    JBPM5 整合Spring3经典案例

    - **Bean管理**:Spring可以管理流程中的业务对象,提供更细粒度的控制和生命周期管理。 ### 4. 部署与运行 - `jbpm_03_for_ant部署.doc`:这个文档很可能是关于使用Ant构建工具来部署和运行JBPM5与Spring3整合...

    spring与jbpm的集成包(符集成方法)

    8. **spring-modules-jbpm31.jar**:这个 JAR 文件很可能是 Spring 与 JBPM 3.1 版本的集成组件,包含了必要的桥接和适配器类,以便于在 Spring 环境中使用 JBPM。 9. **readme.txt**:这个文件通常包含集成指南、...

Global site tag (gtag.js) - Google Analytics