spring AOP:@AfterReturning 发送用户通知

前言

spring aop提供了丰富的切面功能,包括了环绕通知、提前通知、结束通知等,能够满足不同的业务场景,有时候需要在方法成功执行完成之后才提供切面通知。注解@AfterReturning 就能够很好的实现这个功能。

具体实现

  1. 首先需要一个AOP的切面方法。
import java.lang.reflect.Method;
import java.util.Date;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Aspect
@Component
@Lazy(value = false)
public class UserNotifyAop {

	@Autowired
	IUserNotify iUserNotify;

	@Autowired
	UserNotifyProducer userNotifyProducer;

	@Autowired
	UserAuthRepository userAuthRepository;


	@AfterReturning(value = "@annotation(userNotifyAnnotation)",returning = "userAuth")
	public void after(JoinPoint joinPoint, UserNotifyAnnotation userNotifyAnnotation,Object userAuth) throws Throwable {
		Method method = MethodSignature.class.cast(joinPoint.getSignature()).getMethod();
		Object[] in = joinPoint.getArgs();
		String authType = parseKey(userNotifyAnnotation.authType(), method, in);
		String authValue = parseKey(userNotifyAnnotation.authValue(), method, in);
		String uniqueid = null;
		if (!StringUtils.isEmpty(userNotifyAnnotation.uniqueid())) {
			uniqueid = parseKey(userNotifyAnnotation.uniqueid(), method, in);
		}
		UserNotifyEnum notifyEnum = userNotifyAnnotation.userNotifyEnum();
		if(notifyEnum == UserNotifyEnum.REGISTER){
			UserNotifyDTO<RegisterInfo> userNotifyDTO = new UserNotifyDTO<RegisterInfo>();
			userNotifyDTO.setUserId(((UserAuth)userAuth).getUserId());
			userNotifyDTO.setNotifyTime(new Date());
			userNotifyDTO.setUserNotifyEnum(notifyEnum);
			RegisterInfo registerInfo = new RegisterInfo();
			registerInfo.setMobile(authValue);
			registerInfo.setRegisteTime(((UserAuth)userAuth).getCreatedTs());
			registerInfo.setUniqueid(uniqueid);
			userNotifyDTO.setData(registerInfo);
			userNotifyProducer.send(userNotifyDTO);
		}
		if(notifyEnum == UserNotifyEnum.BIND){
			UserAuth userAuth1 = userAuthRepository.findByTypeAndValue(authType,authValue);
			UserNotifyDTO<BindInfo> userNotifyDTO = new UserNotifyDTO<BindInfo>();
			userNotifyDTO.setUserId((userAuth1.getUserId()));
			userNotifyDTO.setNotifyTime(new Date());
			userNotifyDTO.setUserNotifyEnum(notifyEnum);
			BindInfo bindInfo = new BindInfo();
			bindInfo.setBindType(authType);
			bindInfo.setBindValue(authValue);
			userNotifyDTO.setData(bindInfo);
			userNotifyProducer.send(userNotifyDTO);
		}
	}

	/**
	 * 解析SpEL表达式
	 *
	 * @param key SpEL表达式
	 * @param method 反射得到的方法
	 * @param args 反射得到的方法参数
	 * @return 解析后SpEL表达式对应的值
	 */
	private String parseKey(String key, Method method, Object[] args) {
		// 获取被拦截方法参数名列表(使用Spring支持类库)
		LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
		String[] paraNameArr = u.getParameterNames(method);
		// 使用SpEL进行key的解析
		ExpressionParser parser = new SpelExpressionParser();
		// SpEL上下文
		StandardEvaluationContext context = new StandardEvaluationContext();
		// 把方法参数放入SpEL上下文中
		for (int i = 0; i < paraNameArr.length; i++) {
			// 使用setVariable方法来注册自定义变量
			context.setVariable(paraNameArr[i], args[i]);
		}
		return parser.parseExpression(key).getValue(context, String.class);
	}

@AfterReturning 能够实现获取方法返回值的功能,通过自定义的注解,aop直接切加上自定义通知注解的方法,然后异步发动通知消息。
启动私有方法parseKey 是通过Spel 表达式的方法来解析注解参数,获取具体值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值