1.由于在测试服务器,或者准生产服务器验证开发功能时,不能随意更改功能代码,造成了大量的时间消耗,所以使用spring的面向切面编程(aop),来简化测试工作。就项目测试人员要求,要求我们某一个单一接口实现接收响应时超时,我们实现思路是,在我们接收三方系统给的响应后,利用aop将响应信息返回给系统的其他节点前修改响应,这样就能满足测试需求。
本文只是提供一种测试思路。如果想看aop详细介绍和使用,请移驾。之后有时间会后续更新aop 相关接收和使用配置文件实现aop功能。
流程:
代码:
package com.ruim.ifsp.pafyhome.aop;
import com.ruim.ifsp.framework.utils.IfspSpringContextUtils;
import com.ruim.ifsp.log.IfspLoggerFactory;
import com.ruim.ifsp.pafyhome.bean.response.base.CommonTxnSimpleResponse;
import com.ruim.ifsp.pafyhome.dao.PayChannelDao;
import com.ruim.ifsp.utils.message.IfspFastJsonUtil;
import com.ruim.ifsp.utils.verify.IfspDataVerifyUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @ClassName PayhomeAspect
* @Description
* @Author Administrator
* @Date 2020/3/4 16:24
**/
@Aspect
@Component
@Order(200)
public class PayhomeAspect {
//定义日志
private Logger log = IfspLoggerFactory.getLogger(payhomeAspect.class);
//定义切点
//1.广电测试 使用注解配置切点 GDPaymentServiceImp类的call 方法。
@Pointcut(value = "execution(public * com.ruim.ifsp.pafyhome.service.imp.GDPaymentServiceImp.call(..))")
public void GDPay(){
}
//2.社保测试 使用注解配置切点 PerBankPayInsurantChargeServiceImpl类call方法
@Pointcut(value = "execution(public * com.ruim.ifsp.pafyhome.service.imp.PerBankPayInsurantChargeServiceImpl.call(..))")
public void SBPay(){
}
//3.电费缴费测试,没有配置
public void DFPay(){
}
/**
*@author lxw
*@date 2020/3/4
*@desc 切面方法,使用环绕通知
*@param arg
*@return java.lang.Object
**/
@Around("GDPay()||SBPay()")
public Object aspectMethod(ProceedingJoinPoint arg) throws Throwable {
Object object = arg.proceed();
try {
log.info("============================开始处理payhomeAspect=================");
Map<String,Object> paramsMap = IfspFastJsonUtil.objectTomap(arg.getArgs()[0]);
String txnCode = IfspDataVerifyUtil.isEmptyMap(paramsMap)?"":(String) paramsMap.get("txnCode");
PayChannelDao payChannelDao = IfspSpringContextUtils.getInstance().getBean(PayChannelDao.class);
String preKey = payChannelDao.selectByPrimaryKey("PAYHOME_REJECT","303").getParamSysInfo();
log.info("txnCode:{},preKey:{}",txnCode,preKey);
if (preKey.equals("TRUE")){
log.info("============================payhomeAspect超时处理===========================");
if ("303822".equals(txnCode)||"303922".equals(txnCode)){ //广电和社保缴费设置成超时
CommonTxnSimpleResponse resp = (CommonTxnSimpleResponse)object;
resp.setRespCode("3030003");
resp.setRespMsg("主机支付通讯超时,请稍后发起查询交易查询结果!");
return resp;
}
}
}catch (Exception e){
log.info("处理异常:{}",e.getMessage());
return object;
}
return object;
}
}
需要注意的是:
1.在入口(controller)调用实现类(serviceImpl)的时候,首先确认 bean 的注入是接口注入,还是类注入的。
1. 使用类注入:
@Resource(name = "aisleService")
private AisleServiceImpl aisleService;
2. 使用接口注入:
@Resource(name = "aisleService")
private IAisleService aisleService;
1.不能使用JDK的动态代理注入,原因是jdk的动态代理不支持类注入,只支持接口方式注入;
2.可以使用jdk动态代理注入;
如果要使用代码1的方式,必须使用cglib代理;否则会出现:org.springframework.beans.factory.BeanNotOfRequiredTypeException
这个异常。需要spring配置文件中启用代理 <aop:config proxy-target-class="true">。
2.aop切入的类必须在spring中注册bean,否则无法实现功能。