복붙노트

[SPRING] 어떻게 Activiti JavaDelegate에서 스프링 빈에 액세스 할 수 있습니까?

SPRING

어떻게 Activiti JavaDelegate에서 스프링 빈에 액세스 할 수 있습니까?

Activiti 5.5와 작동하고 문제가있는 간단한 Spring 예제를 얻으려고합니다. % activiti_home % / apps / apache-tomcat-6.0.32 / webapps / activiti-rest에서 activiti로 구성된 프로세스 엔진을 사용하고 있습니다.

나는 스프링 커스텀 파일을 수정하여 커스텀 스프링 설정 파일의 include를 수행했다 :

<import resource="classpath*:applicationContext*.xml"/> 

applicationContext.xml 파일을 activiti-rest / WEB-INF / classes 폴더에 배포했습니다. Activiti가 정상적으로 시작되고, 내 bean 생성자에서 System.out.println을 볼 수 있습니다. 그래서 스프링 구성이 읽혀지고 bean이 생성되고 있음을 알 수 있습니다. JavaDelegate를 구현하고 빈을 주입 한 클래스 용 스프링 빈을 만들었습니다. 항상 null이됩니다.

여기 내 Spring Config가 있습니다 :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx" 
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <bean id="myBean" class="org.bpmn.examples.MyBean"/>
    <bean id="taskBean" class="org.bpmn.examples.GetBeanTest">
            <property name="myBean" ref="myBean"/>
    </bean>
</beans>

여기 내 콩이있다.

package org.bpmn.examples;

import java.io.Serializable;

public class MyBean implements Serializable {

    public MyBean() {
        super();
        System.out.println("<========================== myBean ===========================>");
        System.out.println("<========================== myBean ===========================>");
        System.out.println("<========================== myBean ===========================>");
    }
    /**
     * 
     */
    private static final long serialVersionUID = -2867207654072787909L;
    Long id;
    String description;

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

}

다음은 JavaDelegate를 구현하는 클래스입니다.

package org.bpmn.examples;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;

public class GetBeanTest implements JavaDelegate {

    private MyBean myBean;

    @Override
    public void execute(DelegateExecution execution) throws Exception {
        if(myBean == null){
            System.out.println("Bean was null!");
        }else{
            System.out.println("Bean is valid!");
        }

    }

    public void setMyBean(MyBean myBean) {
        this.myBean = myBean;
    }
}

이 모든 것은 꽤 솔직하게 보입니다. 그러나 문제는 Activiti가 JavaService 작업에서 호출되는 클래스에서 스프링 빈을 사용하지 않고 새로운 인스턴스를 생성한다는 것입니다.

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="TestSpringConfig" name="TestSpringConfig">
    <documentation>Place documentation for the 'TestSpringConfig' process here.</documentation>
    <startEvent id="startevent1" name="Start"></startEvent>
    <serviceTask id="servicetask1" name="BeanTest" activiti:class="org.bpmn.examples.GetBeanTest"></serviceTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
    <sequenceFlow id="flow2" name="" sourceRef="servicetask1" targetRef="endevent1"></sequenceFlow>
  </process>
</definitions>

Spring Bean에 대한 참조는 여기에있는 것과 같은 간단한 것 또는 JPA Entity로 구성된 것 중 어느 것을 얻을 수 있습니까?

모든 / 모든 답변 감사!

6.28.2011 업데이트 : 독립 실행 형 StandaloneProcessEngineConfiguration 대신 SpringProcessEngineConfiguration을 사용하도록 activiti-rest 응용 프로그램을 변경하려고 시도하면서 activiti-cfg.jar 파일에서 activiti-cfg.xml 파일을 변경하고 Tomcat을 다시 시작했습니다.

다음과 같이 xml 파일을 변경합니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
        <property name="driverClass" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:tcp://localhost/activiti" />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean>

  <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"/>
  <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
    <property name="processEngineConfiguration" ref="processEngineConfiguration" />
  </bean>

  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
  </bean>

  <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    <property name="dataSource" ref="dataSource" />
    <property name="transactionManager" ref="transactionManager" />
    <property name="databaseSchemaUpdate" value="true" />
    <property name="jobExecutorActivate" value="false" />
  </bean>

  <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
    <property name="processEngineConfiguration" ref="processEngineConfiguration" />
  </bean>

  <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
  <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
  <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
  <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
  <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />

</beans>

Tomcat을 다시 시작할 때 예외가 나타나지 않지만 탐색기를 시작하고 로그인하려고하면 다음과 같은 예외가 발생합니다.

INFO: Server startup in 12011 ms
10:32:02,338  ERROR [extensions.webscripts.AbstractRuntime] Exception from executeScript - redirecting to status template error: 05280000 Wrapped Exception (with status template): null
org.springframework.extensions.webscripts.WebScriptException: 05280000 Wrapped Exception (with status template): null
    at org.springframework.extensions.webscripts.AbstractWebScript.createStatusException(AbstractWebScript.java:742)
    at org.springframework.extensions.webscripts.DeclarativeWebScript.execute(DeclarativeWebScript.java:167)

해결법

  1. ==============================

    1.내 프로젝트 중 하나는 봄에 Activiti를 사용합니다. 나는 JavaDelagate가 문제가 될 수 있다고 생각한다. 이런 식으로 스프링 빈마다 activiti의 서비스 작업을 호출 할 수 있습니다.

    내 프로젝트 중 하나는 봄에 Activiti를 사용합니다. 나는 JavaDelagate가 문제가 될 수 있다고 생각한다. 이런 식으로 스프링 빈마다 activiti의 서비스 작업을 호출 할 수 있습니다.

    빈 정의 :

    <bean id="exampleBean" class="org.bpmn.examples.ExampleBean"/>
    

    XML 활동 :

    <serviceTask id="servicetask" name="Example" activiti:expression="${exampleBean.doSomething()}"></serviceTask>
    

    프로세스 변수와 같은 함수에 매개 변수를 전달할 수도 있습니다.

    <serviceTask id="servicetask" name="Example" activiti:expression="${exampleBean.doSomething(processVariable)}"></serviceTask>
    

    나는 항상 이런 식으로 서비스 작업을 사용하며 싱글 톤 빈에 문제가 없다. 희망이 도움이됩니다. 내가 당신의 문제를 이해하지 못했다면 의견을 말하십시오.

    최신 정보:

    내 프로젝트는 임베디드 워크 플로우 엔진처럼 activiti를 사용합니다. Activiti는 webapp에 동일한 applicationContext를 사용합니다.

    내 프로세스 엔진 구성 :

    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
            <property name="databaseType" value="mssql" />
            <property name="dataSource" ref="dataSource" />
            <property name="transactionManager" ref="transactionManager" />
            <property name="databaseSchemaUpdate" value="true" />
            <property name="jobExecutorActivate" value="true" />
            <property name="deploymentResources" value="classpath*:/diagrams/*.bpmn20.xml" />           
        </bean> 
    
    
        <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
            <property name="processEngineConfiguration" ref="processEngineConfiguration" />
        </bean>
    
  2. ==============================

    2.나는 사용하고있다. @Autowired

    나는 사용하고있다. @Autowired

    내 의존성을 가져 오지. JavaDelegate는 Spring에 의해 인스턴스화되지 않으므로,

    applicationContext.getAutowireCapableBeanFactory().autowireBean(this);
    

    모든 Delegate를 Delegate에 삽입하는 My Delegate의 Superclass 생성자 http://sujitpal.blogspot.com/2007/03/accessing-spring-beans-from-legacy-code.html에서 응답을 제공하는 곳에서 applicationContext를 가져올 위치가 궁금 할 수 있습니다.

  3. ==============================

    3.Activiti는 스프링 컨테이너에서 인스턴스를 가져와야한다는 사실을 Activiti가 인식하지 못하기 때문에 항상 새로운 인스턴스를 생성합니다.

    Activiti는 스프링 컨테이너에서 인스턴스를 가져와야한다는 사실을 Activiti가 인식하지 못하기 때문에 항상 새로운 인스턴스를 생성합니다.

    이 자원을 아직 확인하지 않은 경우 :

    http://www.activiti.org/userguide/index.html#springintegration

    필요한 항목 (예 : ProcessEngineFactoryBean)

  4. from https://stackoverflow.com/questions/6474324/how-can-i-access-a-spring-bean-in-activiti-javadelegate by cc-by-sa and MIT license