spring aop+queue+多线程轮询消费实现方法拦截后的异步处理

本文介绍了如何利用Spring AOP进行方法拦截,并结合队列和多线程实现异步处理。通过创建切点、定义队列消费者和服务类,以及处理未捕获异常,来实现日志记录和计费功能。
摘要由CSDN通过智能技术生成

一、spring aop的优缺点

优点:低侵入式设计,耦合性低,维护性高。
缺点:采用反射生成代理对象,性能上有瓶颈;织入增强处理都是同步的单一线程,总是在方法返回之前进行。

二、业务场景分析

对一般的业务场景,我们采用aop是可以的。但是如果我们的织入处理很复杂,而且与方法的返回无关。比如复杂日志的记录,这时候我们考虑异步方式去完成代理方法的增强处理。大型的系统,可以采用aop+MQ,自己维护一个消息队列系统,在对方法进行拦截后,只需发送消息到MQ系统,告诉另一个业务系统需要做什么。现在的业务场景是,下游客户调用我们API,我们API调用上游API,需要将调用情况记录数据库进行计费。这里,通过一个单例队列来存放“消息”,并开启一个线程轮询从队列取“消息”,再进行“消费”处理。

三、代码实践

这里采用AspectJ的方式,完成aop动态代理:
存放消息的队列:
/**
 * 存放消息的队列
 * 这里采用无界队列LinkedBlockingQueue,由于存的对象可能使上游计费对象,
 * 也可能是下游计费对象,这里用泛型
 * @author robert
 *
 * @param <T>
 */
@Component
public class ChargingQueue<T> {
	private BlockingQueue<T> chargeQueue = new LinkedBlockingQueue<T>();

	public void add(T t) {
		chargeQueue.add(t);
	}

	public T poll() throws InterruptedException {
		return chargeQueue.poll(1, TimeUnit.SECONDS);
	}

}


切点类:
/**
 * 
 * @ClassName: ChargeAspect
 * @Description: 切点类
 * @author robert
 * @date 2017-7-6
 *
 */
@Aspect
@Component
public class ChargeAspect {
	@Autowired
	private ChargingQueue chargingQueue;
	// 本地异常日志记录对象
	private static final Logger logger = Logger.getLogger(ChargeAspect.class);

	// 上游计费切点
	@Pointcut("@annotation(com.roman.api.aop.async.charge.UpStreamChargingLog)")
	public void upStreamCharging() {
	}

	// 下游计费切点
	@Pointcut("@annotation(com.roman.api.aop.async.charge.DownStreamChargingLog)")
	public void downStreamCharging(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值