[英]How to access Spring Beans in Activiti JavaDelegate tasks
[英]Tasks with autowired Spring beans in Activiti
從任務中調用服務的方法時,在Activiti Explorer中使用Spring的自動裝配功能時遇到問題。 這個想法是讓Service Task在Spring @Service bean上調用方法之一,以便使用@Autowired JPARepository持久化數據。
問題是,執行服務任務后,由於未正確實例化myService中的@Autowired存儲庫,我得到了空指針異常。
那么我的問題是, 如何才能從任務服務中正確調用Spring bean?
該JavaDelegate方法不起作用使用Spring,和我試着去為“表達”的方式,如建議在這里無濟於事。
這是服務任務運行方法的代碼,其運行方式為:
activiti:expression="${testServiceTask.doSomething()}"
//被調用的java類
public class testServiceTask {
@Autowired
private TestServiceDummy serviceDummy;
public void doSomething() {
serviceDummy.run(); // NPE here, the serviceDummy is null when called
}
// Getters and Setters for the testServiceDummy omitted for brevity
}
這是我的服務:
public interface TestServiceDummy {
public void createUser();
}
@Service(value = "testServiceDummyImpl")
@Transactional(readOnly = true)
public class TestServiceDummyImpl implements TestServiceDummy {
@Autowired
private UserRepository userRepo;
@Override
public void createUser() {
User u = new User();
userRepo.save(u);
}
// Getters and Setters for userRepo omitted for brevity
}
從我們的Web應用程序中調用時,同樣的東西可以正常工作(以@ManagedProperty調用服務可以正常工作),因此嵌入式項目的配置似乎可以。
這是Activiti Explorer的applicationContext文件:
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">
<import resource="classpath*:/applicationContextCore.xml" />
<context:property-placeholder location="classpath*:jdbc.properties" />
<!-- Scan this classpath for annotated components that will be auto-registered
as Spring beans -->
<context:annotation-config /> <!-- this should take care of the @Autowiring issue -->
<!-- scan the embedded project's components -->
<context:component-scan base-package="my.project.*" />
<jpa:repositories base-package="my.project.repositories*" />
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- Automatically translate hibernate/jpa exceptions into Spring's generic
DataAccessException hierarchy for those classes annotated with Repository -->
<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="testServiceDummy" class="edu.bedelias.services.TestServiceDummyImpl" />
<!-- JPA Entity Manager Factory -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
<property name="packagesToScan">
<list>
<value>edu.bedelias.*</value>
</list>
</property>
<property name="jpaProperties">
<props>
<!-- set HibernateJpaVendorAdapter's behavior: 'create' = build a new
DB on each run; 'update' = modify an existing database; 'create-drop' = 'create'
and also drops tables when Hibernate closes; 'validate' = makes no changes
to the database -->
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
</props>
</property>
</bean>
<bean id="hibernateJpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="false" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
<property name="maxStatements" value="${jdbc.maxStatements}" />
<property name="minPoolSize" value="${jdbc.minPoolSize}" />
</bean>
<!-- Transaction Manager is defined -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Hijack the current @Session scope annotation on each @Service and make
it last only for the duration of the thread -->
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="session">
<bean class="org.springframework.context.support.SimpleThreadScope" />
</entry>
</map>
</property>
</bean>
<!-- Enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven />
<bean id="dbProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:db.properties" />
<!-- Allow other PropertyPlaceholderConfigurer to run as well -->
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<bean id="demoDataGenerator" class="org.activiti.explorer.demo.DemoDataGenerator">
<property name="processEngine" ref="processEngine" />
</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="true" />
<property name="customFormTypes">
<list>
<ref bean="userFormType" />
</list>
</property>
</bean>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean"
destroy-method="destroy">
<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" />
<bean id="identityService" factory-bean="processEngine"
factory-method="getIdentityService" />
<bean id="activitiLoginHandler" class="org.activiti.explorer.ui.login.DefaultLoginHandler">
<property name="identityService" ref="identityService" />
</bean>
<!-- Include the UI-related wiring. This UI context will be used in the
alfresco activiti admin UI -->
<import resource="activiti-ui-context.xml" />
<!-- Custom form types -->
<bean id="userFormType" class="org.activiti.explorer.form.UserFormType" />
如果有人感到好奇,請在此處找到該項目的URL: Google Code托管的項目
提前致謝,
加斯頓
您是否嘗試使用井號而不是美元?
activiti:expression="#{testServiceTask.doSomething()}"
這在我的Spring + Activiti配置中有效
最終工作:
ClassPathXmlApplicationContext cpx = new ClassPathXmlApplicationContext("classpath:applicationContextActiviti.xml");
TestServiceDummy = (TestServiceDummy) cpx.getBean("testServiceDummy");
其中applicationContextActiviti是自定義的appContext配置文件,其中聲明了TestServiceDummy服務。 我在任務調用的JavaDelegate類中使用它。
基本上,從Activiti Explorer中,我沒有對Spring Bean的可見性(除非弄臟了手 ),所以我要做的是跳過@Autowired並使用舊的手動方法處理bean,然后從調用者類中加載它們。
只是把它留在這里,以防它希望任何未來的旅行者:P
似乎在春季配置文件中未聲明testServiceTask。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.