spring aop expression支持多个表达式配置
准备:
目标类UcUserFilesService 及目标方法insert()方法、update()方法及delete()方法(红色标注的是目标方法)
package com.huajin.userserver.service;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.huajin.baymax.exception.BayMaxBaseException;
import com.huajin.common.dto.GlobalDto;
import com.huajin.exchange.domain.PageData;
import com.huajin.exchange.responsecode.UserServerResponseCode;
import com.huajin.exchange.userservice.domain.response.FileInfo;
import com.huajin.exchange.userservice.domain.response.UcUser;
import com.huajin.exchange.userservice.domain.response.UcUserFiles;
import com.huajin.exchange.utils.ParamMapUtil;
import com.huajin.exchange.utils.UUIDUtil;
import com.huajin.userserver.datasupport.UcUserFilesDataSupportService;
import com.huajin.userserver.service.ucuser.UcUserService;
/**
* UcUserFilesService
*
* @author auto-generator
* 2015-06-30 26:13:38
*/
@Service
public class UcUserFilesService {
@Autowired
private UcUserFilesDataSupportService ucUserFilesDataSupportService;
@Autowired
private SysParamService sysParamService;
@Autowired
private UcUserService ucUserService;
public UcUserFiles getById(GlobalDto globalDto, Integer id) {
return ucUserFilesDataSupportService.getById(globalDto, id);
}
public FileInfo getByUUID(GlobalDto globalDto,String userFileGuid) {
UcUserFiles ucUserFiles = ucUserFilesDataSupportService.getByUUID(globalDto, userFileGuid);
if (Objects.isNull(ucUserFiles)) {
throw new BayMaxBaseException(UserServerResponseCode.USER_NOT_EXIST, null);
}
FileInfo fileInfo = new FileInfo();
fileInfo.setFilePath(getFilePath(ucUserFiles.getUserId()));
fileInfo.setIsOpen(0);
fileInfo.setOwerUserId(ucUserFiles.getUserId());
UcUser ucUser = ucUserService.getSimpleById(globalDto, ucUserFiles.getUserId());
fileInfo.setOwerMemberId(ucUser.getOwnerUserId());
fileInfo.setStatus(ucUser.getUserStatus());
return fileInfo;
}
private String getFilePath(int userId) {
return sysParamService.userFilePath() + userId + File.separator;
}
public PageData<UcUserFiles> select(GlobalDto globalDto, Map<String, Object> map) {
List<UcUserFiles> list = ucUserFilesDataSupportService.select(globalDto, map);
return new PageData<>(ParamMapUtil.getTotalsize(map, list.size()), ParamMapUtil.getTotalpage(map, 1), list);
}
public Integer insert(GlobalDto globalDto, UcUserFiles o) {
o.allFileNamesSplit(this.getFilePath(o.getUserId()));
o.setUserFileGuid(UUIDUtil.getUUID());
ucUserFilesDataSupportService.insert(globalDto, o);
return o.getId();
}
public Integer update(GlobalDto globalDto, UcUserFiles o) {
o.allFileNamesSplit(this.getFilePath(o.getUserId()));
ucUserFilesDataSupportService.update(globalDto, o);
return o.getId();
}
public void delete(GlobalDto globalDto, Integer id) {
ucUserFilesDataSupportService.delete(globalDto, id);
}
/**
* 不分页查询列表记录
*
* @param globalDto
* @param map
* @return
* @author hongwei.lian
* @date 2018年11月13日 下午12:01:23
*/
public List<UcUserFiles> findByCondition(GlobalDto globalDto, Map<String, Object> map) {
return ucUserFilesDataSupportService.select(globalDto, map);
}
/**
* 根据用户Id和文件类型fileType查询附件记录
*
* @param userId
* @param fileType
* @return
* @author hongwei.lian
* @date 2018年11月13日 下午12:01:38
*/
public UcUserFiles getUserFileByUserIdAndFileType(Integer userId, Integer fileType) {
Map<String, Object> param = new HashMap<>(2);
param.put("userId", userId);
param.put("fileType", fileType);
List<UcUserFiles> list = this.findByCondition(null, param);
return CollectionUtils.isEmpty(list) ? null : list.get(0);
}
}
方案一:JavaConfig方式配置
切面、切点及前置通知UserFileChangeRecordAspect
package com.huajin.userserver.aop;
import java.util.Objects;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.huajin.exchange.enums.user.UserFileTypeDesc;
import com.huajin.exchange.userservice.domain.response.UcUserFiles;
import com.huajin.userserver.enums.UserFileOperateEnum;
import com.huajin.userserver.service.RedisService;
import com.huajin.userserver.service.UcUserFilesService;
import com.huajin.userserver.utils.CacheKey;
import lombok.extern.slf4j.Slf4j;
/**
* 用户文件操作记录切面
*
* @author hongwei.lian
* @date 2018年11月12日 下午7:23:08
*/
@Aspect
@Component("userFileChangeRecordAspect")
@Slf4j
public class UserFileChangeRecordAspect {
@Autowired
private UcUserFilesService ucUserFilesService;
@Autowired
private RedisService redisService;
/**
* 用户文件操作切点
*
* @author hongwei.lian
* @date 2018年11月13日 下午1:59:26
*/
@Pointcut("execution(* com.huajin.userserver.service.UcUserFilesService.insert(..)) || " +
"execution(* com.huajin.userserver.service.UcUserFilesService.update(..)) || " +
"execution(* com.huajin.userserver.service.UcUserFilesService.delete(..))")
public void pointCut() {}
/**
* 用户文件操作记录
*
* @param point
* @param returnValue
* @author hongwei.lian
* @date 2018年11月12日 下午7:24:30
*/
@Before("pointCut()")
public void userFileOperatorRecord(JoinPoint joinPoint) {
try {
//-- 1、获取目标方法名称和目标方法参数信息,获取旧文件记录
UcUserFiles olducUserFiles = null;
Integer userId = null;
Integer fileType = null;
String methodName = joinPoint.getSignature().getName();
if (Objects.equals(methodName, UserFileOperateEnum.DELETE.getDesc())) {
Integer id = (Integer) joinPoint.getArgs()[1];
olducUserFiles = ucUserFilesService.getById(null, id);
if (Objects.nonNull(olducUserFiles)) {
userId = olducUserFiles.getUserId();
fileType = olducUserFiles.getFileType();
}
} else {
UcUserFiles ucUserFiles = (UcUserFiles) joinPoint.getArgs()[1];
if (Objects.nonNull(ucUserFiles)) {
userId = ucUserFiles.getUserId();
fileType = ucUserFiles.getFileType();
}
olducUserFiles = ucUserFilesService.getUserFileByUserIdAndFileType(userId, fileType);
}
//-- 组装用户文件缓存key
String userInfoKey = "";
if (Objects.equals(fileType, UserFileTypeDesc.入会申请书.value)) {
userInfoKey = CacheKey.REDISCACHEKEY_USERFILE_APPLYMEMBERSHIP + userId;
} else if (Objects.equals(fileType, UserFileTypeDesc.经办人身份证.value)) {
userInfoKey = CacheKey.REDISCACHEKEY_USERFILE_OPERATORCARD + userId;
} else if (Objects.equals(fileType, UserFileTypeDesc.机构营业执照.value)) {
userInfoKey = CacheKey.REDISCACHEKEY_USERFILE_BUSINESSLICENSE + userId;
} else if (Objects.equals(fileType, UserFileTypeDesc.法定代表人身份证.value)) {
userInfoKey = CacheKey.REDISCACHEKEY_USERFILE_REPRESENTATIVECARD + userId;
}
//-- 3、判断缓存中是否存在这个key,不存在则新增
boolean nonStringKey = redisService.nonStringKey(userInfoKey);
if (nonStringKey) {
redisService.setStringKey(userInfoKey, Objects.isNull(olducUserFiles) ? "" : olducUserFiles.allFileNames());
}
} catch (Exception e) {
log.error("", e);
}
}
}
从上面的JavaConfig配置可以看出spring aop expression是支持多个表达式配置的,中间可以使用逻辑运算符,支持的有and、or、也可以使用||、&&、!。需要注意一点使用and或者or注意大小写,尽量都写作小写,原因还需要深究。
方案二:XML方式配置
spring-aop.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
"
default-lazy-init="true">
<aop:config>
<!-- 切面 -->
<aop:aspect ref="userFileChangeRecordAspect">
<!-- 切点 -->
<aop:pointcut id="pointCut" expression="
execution(* com.huajin.userserver.service.UcUserFilesService.insert(..)) or
execution(* com.huajin.userserver.service.UcUserFilesService.update(..)) or
execution(* com.huajin.userserver.service.UcUserFilesService.delete(..))"/>
<!-- 通知 -->
<aop:before pointcut-ref="pointCut" method="userFileOperatorRecord"/>
</aop:aspect>
</aop:config>
</beans>
相应的userFileChangeRecordAspect的userFileOperatorRecord方法逻辑和上面JavaConfig方式的方法逻辑是一样的,不再赘述
参考文章:
http://docs.jboss.org/jbossaop/docs/2.0.0.GA/docs/aspect-framework/reference/en/html/pointcuts.html
https://blog.csdn.net/z_dendy/article/details/9447857
https://blog.csdn.net/u010746364/article/details/53288818