Activiti工作流学习(三)Activiti工作流与spring集成
一.前言
前面Activiti工作流的学习,说明了Activiti的基本应用,在我们开发中可以根据实际的业务参考Activiti的API去更好的理解以及巩固。我们实际的开发中我们基本上都使用spring框架进行开发,现在来说明一下Activiti工作流与spring集成,Activiti工作流与spring集成还算比较简单,可以参考Activiti的API来进行整合。
二.Activiti常用的表
---------------------------------------------部署对象和流程定义相关的表--------------------------------------------- --部署对象信息表
SELECT T.*, T.ROWID FROM ACT_RE_DEPLOYMENT T; --流程定义表
--ID_ 由KEY_ + VERSION_ + 随机生成是数组成
SELECT T.*, T.ROWID FROM ACT_RE_PROCDEF T where t.category_='1' order by t.version_ asc; --资源文件表
SELECT T.*, T.ROWID FROM ACT_GE_BYTEARRAY T; --主键生成策略表
SELECT T.*, T.ROWID FROM ACT_GE_PROPERTY T; ------------------------------------------流程实例、执行对象、任务------------------------------------------------ --正在执行的执行对象表
-- 执行ID_ 56 流程实例ID_ 56 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 正在运行的任务定义ID_ 【可变】 USERTASKE736BEF8-4133-7B3D-F510-7B2DE7BEA8C6
SELECT T.*, T.ROWID FROM ACT_RU_EXECUTION T; --流程实例历史表 开始信息
--历史流程定义ID_ 56 流程S实例ID_ 56 业务KEY_10000001 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 开始任务节点ID_ STARTEVENT52B3145F-C133-7B3D-F50F-E6D48BA60EAE
SELECT T.*, T.ROWID FROM ACT_HI_PROCINST T; --正在执行的任务对象表
--任务ID_ 68 执行ID_ 56 流程实例ID_ 56 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 任务节点ID_ USERTASKE736BEF8-4133-7B3D-F510-7B2DE7BEA8C6
SELECT T.*, T.ROWID FROM ACT_RU_TASK T; --历史任务流程实例信息
--历史任务ID_ 68 流程实例ID_ 56 执行实例ID_ 56 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 任务节点ID_ USERTASKE736BEF8-4133-7B3D-F510-7B2DE7BEA8C6 表单KEY_ /PAGES/HOLIDAY/HOLIDAYMANAGE/HOLIDAYFORMHANDLE.JSP
--历史任务ID_ 74 流程实例ID_ 56 执行实例ID_ 56 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 任务节点ID_ USERTASK04A84BE1-1133-7B3D-F511-1D0B7BB0A668 表单KEY_ /PAGES/HOLIDAY/HOLIDAYMANAGE/HOLIDAYFORMVIEW.JSP
SELECT T.*, T.ROWID FROM ACT_HI_TASKINST T; --所有活动节点历史任务表
--历史任务ID_58 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 流程实例ID_ 56 流程执行ID_ 56 任务节点ID_ STARTEVENT52B3145F-C133-7B3D-F50F-E6D48BA60EAE
--历史任务ID_67 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 流程实例ID_ 56 流程执行ID_ 56 任务节点ID_ USERTASKE736BEF8-4133-7B3D-F510-7B2DE7BEA8C6 任务ID_ 68
--历史任务ID_73 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 流程实例ID_ 56 流程执行ID_ 56 任务节点ID_ USERTASK04A84BE1-1133-7B3D-F511-1D0B7BB0A668 任务ID_ 74
SELECT T.*, T.ROWID FROM ACT_HI_ACTINST T; ----------------------------------------流程变量信息--------------------------------------------------
--正在执行的流程变量信息
SELECT T.*, T.ROWID FROM ACT_RU_VARIABLE T; --历史流程变量信息 存放历史表单重要信息
--流程实例ID_ 56 执行实例ID_ 56 任务ID_
SELECT T.*, T.ROWID FROM ACT_HI_VARINST T; -------------------------------------------历史意见信息----------------------------------------------- --历史审批意见表
--任务ID_ 68 流程定义ID_ 56
SELECT T.*, T.ROWID FROM ACT_HI_COMMENT T; -----------------------------------------节点参与者信息-------------------------------------------------
--任务办理人表(个人任务、组任务)
SELECT T.*, T.ROWID FROM ACT_RU_IDENTITYLINK T; --历史任务办理人表(个人任务、组任务)
SELECT T.*, T.ROWID FROM ACT_HI_IDENTITYLINK T; --临时对象
SELECT T.*, T.ROWID FROM EA_IST.IST_APPR_BUSI_DATA T
三.Activiti与spring整合xml配置文件
向spring配置文件中,添加一个spring-workflow2-activiti.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" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!--工作流引擎配置 -->
<bean id="processEngineConfiguration" class="com.shine.workflow2.spring.ShineSpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseSchemaUpdate" value="false" />
<property name="jobExecutorActivate" value="false" />
<!-- 组织机构适配 -->
<property name="organizationConnector" ref="organizationAdapter" /> </bean> <!-- 组织机构适配实现 -->
<bean id="organizationAdapter" class="com.shine.workflow2.organization.impl.OrganizationAdapter" /> <!--工作流引擎 -->
<bean id="processEngine" class="com.shine.workflow2.spring.ShineProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean> <!--扩展服务 -->
<bean id="processDefinitionService" factory-bean="processEngine"
factory-method="getProcessDefinitionService" />
<bean id="processLogService" factory-bean="processEngine"
factory-method="getProcessLogService" />
<bean id="processManagementService" factory-bean="processEngine"
factory-method="getProcessManagementService" /> <!--原生服务 -->
<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="formService" factory-bean="processEngine"
factory-method="getFormService" />
<bean id="identityService" factory-bean="processEngine"
factory-method="getIdentityService" /> </beans>
四.Activiti工作流常用service
1.BaseProcessService
/**
*
*/
package com.shine.eosp.workflow2.common.process; import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task; import com.shine.workflow2.exception.WorkflowException; /**
*
* 类说明: 常用工作流核心操作封装 .
*
* <pre>
* 修改日期 修改人 修改原因
* 2016-6-2 hongwz 新建
* </pre>
*/
public interface BaseProcessService { /**
* 方法说明 : 根据流程定义Key查询最新流程定义.
*
* @param processDefinitionKey
* @throws WorkflowException
*/
public ProcessDefinition findLatestProcessDefinitionByPrcDefKey(String processDefinitionKey) throws WorkflowException; /**
* 方法说明 : 根据流程定义Id查询流程定义.
*
* @param processDefinitionId 流程定义Id
* @throws WorkflowException
*/
public ProcessDefinitionEntity findProcessDefinitionEntityByProcDefId(String processDefinitionId) throws WorkflowException; /**
*
* 方法说明 : 根据流程实例Id查询流程实例.
*
* @param processInstanceId 流程实例Id
* @return
* @throws WorkflowException
*/
public ProcessInstance findProcessInstanceByProcInst(String processInstanceId) throws WorkflowException; /**
* 根据流程实例Id查询流程实例.
*
* @param processInstanceId
* @throws WorkflowException
*/
public Execution findExecutionByProcInst(String processInstanceId) throws WorkflowException; /**
* 方法说明 : 根据流程实例Id查询任务.
*
* @param processInstanceId 流程实例Id
* @throws WorkflowException
*/
public Task findTaskByProcInstId(String processInstanceId) throws WorkflowException; /**
* 方法说明 : 根据实例Id查询任务.
*
* @param executionId 实例Id
* @throws WorkflowException
*/
public Task findTaskByExecutionId(String executionId) throws WorkflowException; /**
* 方法说明 : 根据活动节点查询任务定义.
*
* @param activityImpl 活动节点
* @throws WorkflowException
*/
public TaskDefinition findTaskDefinitionByActivityImpl(ActivityImpl activityImpl) throws WorkflowException; /**
* 方法说明 : 查询上一个节点.
*
* @param activityImpl 活动节点
* @param activityId 当前活动节点ID
* @param elString
* @throws ShineException
*/
public TaskDefinition beforeTaskDefinition(ActivityImpl activityImpl,String activityId, String elString) throws WorkflowException; /**
* 方法说明 : 查询下一个节点.
*
* @param activityImpl 活动节点
* @param activityId 当前活动节点ID
* @param elString
* @throws ShineException
*/
public TaskDefinition nextTaskDefinition(ActivityImpl activityImpl,String activityId, String elString) throws WorkflowException; /**
* 方法说明: 根据活动节点、活动线路查询线路的连接线.
*
* @throws WorkflowException
*/
public PvmActivity findPvmActivity(ActivityImpl activityImpl, String transitions) throws WorkflowException; /**
* 方法说明 :根据流程定义Id查询任务定义
*
* @param processDefinitionId 流程定义Id
* @return
* @throws WorkflowException
*/
public TaskDefinition findTaskDefinition(String processDefinitionId) throws WorkflowException; /**
* 方法说明 : 添加任务意见.
*
* @param taskId 任务Id
* @param processInstanceId 流程实例Id
* @param comment 意见
* @throws WorkflowException
*/
public void addTaskComment(String taskId, String processInstanceId, String comment) throws WorkflowException; /**
* 方法说明 : 拾取任务.
*
* @param taskId 任务Id
* @param operator 办理人
* @throws WorkflowException
*/
public void claimTask(String taskId, String operator) throws WorkflowException; /**
* 方法说明 : 根据流程定义Id查询最新流程定义.
*
* @param processDefinitionId 流程定义Id
* @return
* @throws WorkflowException
*/
public ProcessDefinition findProcessDefinitionByPrcDefId(String processDefinitionId) throws WorkflowException;
}
2.BaseProcessServiceImpl
/**
*
*/
package com.shine.eosp.workflow2.common.process; import java.util.Iterator;
import java.util.List; import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import com.shine.util.CollectionUtil;
import com.shine.workflow2.exception.WorkflowException; /**
*
* 类说明: 常用工作流核心操作封装 .
*
* <pre>
* 修改日期 修改人 修改原因
* 2016-6-2 hongwz 新建
* </pre>
*/
public class BaseProcessServiceImpl implements BaseProcessService { /**
* log.
*/
private static Logger logger = LoggerFactory.getLogger(BaseProcessServiceImpl.class); @Autowired
private RepositoryService repositoryService; @Autowired
private RuntimeService runtimeService; @Autowired
private TaskService taskService; @Autowired
private HistoryService historyService; /**
* 方法说明 : 根据流程定义Key查询最新流程定义.
*
* @param processDefinitionKey 流程定义Key
* @return
* @throws WorkflowException
*/
@Override
public ProcessDefinition findLatestProcessDefinitionByPrcDefKey(String processDefinitionKey) throws WorkflowException{ ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey(processDefinitionKey)
.latestVersion()
.singleResult();
return processDefinition; } /**
* 方法说明 : 根据流程定义Id查询最新流程定义.
*
* @param processDefinitionId 流程定义Id
* @return
* @throws WorkflowException
*/
@Override
public ProcessDefinition findProcessDefinitionByPrcDefId(String processDefinitionId) throws WorkflowException{
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(processDefinitionId)
.orderByProcessDefinitionVersion()
.desc()
.singleResult(); return processDefinition;
} /**
* 方法说明 : 根据流程定义Id查询流程定义.
*
* @param processDefinitionId 流程定义Id
* @return
* @throws WorkflowException
*/
@Override
public ProcessDefinitionEntity findProcessDefinitionEntityByProcDefId(String processDefinitionId) throws WorkflowException{ ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(processDefinitionId);
return processDefinitionEntity;
} /**
*
* 方法说明 : 根据流程实例Id查询流程实例.
*
* @param processInstanceId 流程实例Id
* @return
* @throws WorkflowException
*/
@Override
public ProcessInstance findProcessInstanceByProcInst(String processInstanceId) throws WorkflowException{
return runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
} /**
* 根据流程实例Id查询流程实例.
*
* @param processInstanceId
* @return
* @throws WorkflowException
*/
@Override
public Execution findExecutionByProcInst(String processInstanceId) throws WorkflowException{
return runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult();
} /**
* 方法说明 : 根据流程实例Id查询任务.
*
* @param processInstanceId 流程实例Id
* @return
* @throws WorkflowException
*/
@Override
public Task findTaskByProcInstId(String processInstanceId) throws WorkflowException{
return taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
} /**
* 方法说明 : 根据实例Id查询任务.
*
* @param executionId 实例Id
* @return
* @throws WorkflowException
*/
@Override
public Task findTaskByExecutionId(String executionId) throws WorkflowException{
return taskService.createTaskQuery().executionId(executionId).singleResult();
} /**
* 方法说明 : 根据活动节点查询任务定义.
*
* @param activityImpl 活动节点
* @return
* @throws WorkflowException
*/
@Override
public TaskDefinition findTaskDefinitionByActivityImpl(ActivityImpl activityImpl) throws WorkflowException{
return ((UserTaskActivityBehavior)activityImpl.getActivityBehavior()).getTaskDefinition();
} /**
* 方法说明 : 查询上一个节点.
*
* @param activityImpl 活动节点
* @param activityId 当前活动节点ID
* @param elString
* @return
* @throws ShineException
*/
@Override
public TaskDefinition beforeTaskDefinition(ActivityImpl activityImpl,String activityId, String elString) throws WorkflowException {
if("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())){
TaskDefinition taskDefinition = null;
if(activityImpl != null){
taskDefinition = findTaskDefinitionByActivityImpl(activityImpl);
}
return taskDefinition;
}else{
List<PvmTransition> inTransitions = activityImpl.getIncomingTransitions(); //通过活动节点查询所有线路
if(!CollectionUtil.isEmpty(inTransitions)){
List<PvmTransition> inTransitionsTemp = null;
for(PvmTransition tr:inTransitions){
PvmActivity ac = tr.getSource(); //获取线路的前节点
if("exclusiveGateway".equals(ac.getProperty("type"))){
inTransitionsTemp = ac.getIncomingTransitions();
if(inTransitionsTemp.size() == 1){
return beforeTaskDefinition((ActivityImpl)inTransitionsTemp.get(0).getSource(), activityId, elString);
}else if(inTransitionsTemp.size() > 1){
for(PvmTransition tr1 : inTransitionsTemp){
Object s = tr1.getProperty("conditionText");
if(elString.equals(StringUtils.replacePattern(StringUtils.trim(s.toString()), " ", ""))){
return beforeTaskDefinition((ActivityImpl)tr1.getSource(), activityId, elString);
}
}
}
}
}
}
return null;
}
} /**
* 方法说明 : 查询下一个节点.
*
* @param activityImpl 活动节点
* @param activityId 当前活动节点ID
* @param elString
* @return
* @throws ShineException
*/
@Override
public TaskDefinition nextTaskDefinition(ActivityImpl activityImpl,String activityId, String elString) throws WorkflowException { if("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())){
TaskDefinition taskDefinition = null;
if(activityImpl != null){
taskDefinition = findTaskDefinitionByActivityImpl(activityImpl);
}
return taskDefinition;
}else{
List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions(); //通过活动节点查询所有线路
if(!CollectionUtil.isEmpty(outTransitions)){
List<PvmTransition> outTransitionsTemp = null;
for(PvmTransition tr:outTransitions){
PvmActivity ac = tr.getDestination(); //获取线路的终点节点
if("exclusiveGateway".equals(ac.getProperty("type"))){
outTransitionsTemp = ac.getOutgoingTransitions();
if(outTransitionsTemp.size() == 1){
return nextTaskDefinition((ActivityImpl)outTransitionsTemp.get(0).getDestination(), activityId, elString);
}else if(outTransitionsTemp.size() > 1){
for(PvmTransition tr1 : outTransitionsTemp){
Object s = tr1.getProperty("conditionText");
if(s != null && elString.equals(StringUtils.replacePattern(StringUtils.trim(s.toString()), " ", ""))){
return nextTaskDefinition((ActivityImpl)tr1.getDestination(), activityId, elString);
}
}
}
}else if("userTask".equals(ac.getProperty("type"))){
return findTaskDefinitionByActivityImpl((ActivityImpl)ac);
}
else if("startEvent".equals(ac.getProperty("type"))){
return findTaskDefinitionByActivityImpl((ActivityImpl)ac);
}
else{
logger.info(ac.getProperty("type").toString());
}
}
}
return null;
} } /**
* 方法说明: 根据活动节点、活动线路查询线路的连接线.
*
* @return
* @throws WorkflowException
*/
@SuppressWarnings("rawtypes")
@Override
public PvmActivity findPvmActivity(ActivityImpl activityImpl, String transitions) throws WorkflowException{ PvmActivity activity = null;
List<PvmTransition> pvmTransitions = activityImpl.getOutgoingTransitions(); //获取所有线路 for (Iterator iterator = pvmTransitions.iterator(); iterator.hasNext();) {
PvmTransition pvmTransition = (PvmTransition) iterator.next();
PvmActivity pvmActivity = pvmTransition.getDestination(); //获取下一个任务节点
String transitionsVal = (String) pvmActivity.getProperty("name");
if(transitions.equals(transitionsVal)){
activity = pvmActivity;
break;
}
}
return activity;
} /**
* 方法说明 :根据流程定义Id查询任务定义
*
* @param processDefinitionId 流程定义Id
* @return
* @throws WorkflowException
*/
@Override
public TaskDefinition findTaskDefinition(String processDefinitionId) throws WorkflowException{ //获取流程定义
ProcessDefinitionEntity processDefinitionEntity = findProcessDefinitionEntityByProcDefId(processDefinitionId);
TaskDefinition tdf = null; if(processDefinitionEntity != null){
List<ActivityImpl> activityImpls = processDefinitionEntity.getActivities(); //获取所有活动的节点
for(int i = activityImpls.size() - 1; i > 0; i-- ){
ActivityImpl activityImpl = activityImpls.get(i);
String startEventType = (String) activityImpl.getProperty("type");
if("startEvent".equals(startEventType)){
tdf = nextTaskDefinition(activityImpl, activityImpl.getId(), null);
}
}
}
return tdf;
} /**
* 方法说明 : 添加任务意见.
*
* @param taskId 任务Id
* @param processInstanceId 流程实例Id
* @param comment 意见
* @throws WorkflowException
*/
@Override
public void addTaskComment(String taskId,String processInstanceId,String comment) throws WorkflowException{
taskService.addComment(taskId, processInstanceId, comment);
} /**
* 方法说明 : 拾取任务.
*
* @param taskId 任务Id
* @param operator 办理人
* @throws WorkflowException
*/
@Override
public void claimTask(String taskId,String operator) throws WorkflowException{
taskService.claim(taskId, operator);
}
}
Activiti工作流学习(三)Activiti工作流与spring集成的更多相关文章
- PowerShell工作流学习-1-嵌套工作流和嵌套函数
关键点: a)嵌套深度没有任何语法限制,但是嵌套三个层次的工作流不支持任何通用参数,包括工作流通用参数 b)嵌套工作流可以调用当前范围和任何父范围内的工作流和函数 c)工作流不允许递归调用,脚本和函数 ...
- PowerShell工作流学习-3-挂起工作流
关键点: a)可使用Suspend-Job或Suspend-Workflow(从工作流中)挂起工作流,无法从工作流中恢复工作流. 例a: Workflow Test-Suspend { $a = Ge ...
- Quartz学习总结(1)——Spring集成Quartz框架
一.Quartz简介 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用.Quartz可以用来创建简 ...
- Activiti工作流学习笔记(四)——工作流引擎中责任链模式的建立与应用原理
原创/朱季谦 本文需要一定责任链模式的基础,主要分成三部分讲解: 一.简单理解责任链模式概念 二.Activiti工作流里责任链模式的建立 三.Activiti工作流里责任链模式的应用 一.简单理解责 ...
- 工作流学习之--PHP工作流插件
一.支持的PHP的工作流插件有: 1. TPFlow(thinkphp work flow):是一款开源的ThinkPHP工作流插件,用来解决OA.ERP.CRM.CMS等等办公软件的审核审批的问题. ...
- PowerShell工作流学习-6-向脚本工作流添加检查点
关键点: a)检查点是工作流当前状态的快照,其中包括变量的当前值以及在该点生成的任何输出,这些信息保存在磁盘. b)检查点数据保存在托管工作流会话的计算机的硬盘上的用户配置文件中. c)当工作流通用参 ...
- 微服务学习三:springboot与springcloud集成之Eurake的使用(server端,client端)
这个多亏了网站上的一个大神的博客: http://blog.csdn.net/forezp/article/details/70148833 强烈推荐学习: 1.springcloud是什么,这个大家 ...
- Shiro学习总结(10)——Spring集成Shiro
1.引入Shiro的Maven依赖 [html] view plain copy <!-- Spring 整合Shiro需要的依赖 --> <dependency> <g ...
- MongoDB的使用学习之(五)Spring集成MongoDB以及简单的CRUD
这篇文章不错:Spring Data - MongoDB 教程 (1.0.0.M1)http://miller-cn.iteye.com/blog/1258859 1.介绍 之前在很多地方一直见到这个 ...
- Shiro学习(12)与Spring集成
Shiro的组件都是JavaBean/POJO式的组件,所以非常容易使用spring进行组件管理,可以非常方便的从ini配置迁移到Spring进行管理,且支持JavaSE应用及Web应用的集成. 在示 ...
随机推荐
- 好用的开源web系统总结
1.论坛 phpwind 一个用wind框架写的论坛 discuz 社区动力 论坛 2.商城 Ecshop 商城腾讯的开源商城项目 一款B2C独立网店系统,系统是基于PHP语言及MYS ...
- gis数据格式转换(数据导入)ConvertFeaCls
本文主要对数据导入等里 常用的不同格式数据创建.转换等 进行代码示例.主要用到IFeatureDataConverter.ConvertFeatureClass方法. 代码如下,难度不大,只是个技巧问 ...
- ArcGIS Server开发教程系列(8)ArcGIS API for Javascript-控件(小部件)
1. 鹰眼 OverviewMap小部件用于在其关联的主地图内较清楚的当前鸟瞰图的范围.当主地图范围变化时,鹰眼图会自动在其空间内更新范围以保持和地图的当前范围保持一致,当鹰眼图空间的地图范围 ...
- 微博RPC框架motan入门笔记
Motan 是一套高性能.易于使用的分布式远程服务调用(RPC)框架. 功能 支持通过spring配置方式集成,无需额外编写代码即可为服务提供分布式调用能力. 支持集成consul.zookeeper ...
- 进入OS前的两步之PendSV(任务切换)
先了解下如何使用PendSV异常.(为何要使用PendSV而不是其他的异常,请参考<cortex-M3权威指南>) 1,如何设定PendSV优先级? NVIC_SYSPRI14 EQU 0 ...
- css3的基本样式
一.css3字体(@font-face) 二.css3动画 三.css3多列 四.CSS3 outline-offset 属性 五.CSS3 resize 属性
- 用JS获取地址栏参数的方法
采用正则表达式获取地址栏参数: function GetQueryString(name) { var reg = new RegExp("(^|&)"+ nam ...
- ps批量处理图片
刚刚有朋友问,ps咋做批量动作呢,其实特别简单,基本一劳永逸,用尺寸做个例子,大家看看就知道了.
- MySql连接数据库和操作(java)
package org.wxd.weixin.util; import java.sql.Connection;import java.sql.DriverManager;import java.sq ...
- WindowsForm公共控件--2016年12月5日
Button text:修改按钮显示的文字 CheckBox Checked:是否选中 CheckedListBox checkedListBox.Items.Add(显示的值,初始选中状态); ch ...