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开发] 在HTML代码里面如何判断IE版本
在上一篇blog里面提到IE有不同的显示模式以及如何用Javascript 来动态判定. Web开发者可以根据不同显示模式导入不同的内容.这篇blog 主要讲如何让静态HTML代码根据不同IE版本显示 ...
- C++11特性:decltype关键字
decltype简介 我们之前使用的typeid运算符来查询一个变量的类型,这种类型查询在运行时进行.RTTI机制为每一个类型产生一个type_info类型的数据,而typeid查询返回的变量相应ty ...
- SSAS动态添加分区(一)
一.动态分区的好处就不说了,随着时间的推移,不可能一个度量值组都放在一个分区中,处理速度非常慢,如何动态添加分区,如何动态处理分区,成为了很多新手BI工程师一个头痛的问题,废话不多说,分享一下我的经验 ...
- 学习 opencv---(3) ROI 区域图像叠加&初级图像混合
在这篇文章里,我们一起学习了在OpenCV中如何定义感兴趣区域ROI,如何使用addWeighted函数进行图像混合操作,以及将ROI和addWeighted函数结合起来使用,对指定区域进行图像混合操 ...
- Java的内存机制
Java 把内存划分成两种:一种是栈内存,另一种是堆内存.在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空 ...
- SpringMVC@RequestBody小细节
关于@RequestBody 参数类型自己的包装类,还是类似String/int,区别: 1.@RequestBody LoginParmar parmar String user_number = ...
- delphi xe4 ini文件不能读取的解决方法
今天发现用inifiles下 tinifile.readstring方法突然不能读数据了,结果把ini文件格式由utf-8改成unicode后就能正常读取了.
- Ubuntu 12.04安装Adobe Reader
原本从Adobe 官方网站下载了 Adobe Reader, 是个rpm包,先用agt-get 装了rpm(sudo apt-get install rpm), 一安装(rpm -ivh AdobeR ...
- ubuntu下安装chrome
首先.题主在试过直接ubuntu终端命令安装chrome失败. 把经历过的错误稍微提一下: 在终端输入 下载安装包 sudo wget https://dl.google.com/linux/dire ...
- Shell判断字符串包含关系的几种方法
现在每次分析网站日志的时候都需要判断百度蜘蛛是不是真实的蜘蛛,nslookup之后需要判断结果中是否包含“baidu”字符串 以下给出一些shell中判断字符串包含的方法,来源程序员问答网站 stac ...