Spring使用注解实现AOP
Posted root_zhb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring使用注解实现AOP相关的知识,希望对你有一定的参考价值。
Spring使用注解实现AOPAOP
1、AOP术语
- target:目标类,需要被代理的类。
- Joinpoint(连接点):所谓连接点是指那些可能被拦截到的方法。例如:所有的方法
- PointCut 切入点:已经被增强的连接点。例如:某个增强的方法
- advice 通知/增强:增强代码。例如:after、before
- Weaving(织入):是指把增强advice应用到目标对象target来创建新的代理对象proxy的过程。
- proxy 代理类
- Aspect(切面):是切入点pointcut和通知advice的结合
一个线是一个特殊的面。
一个切入点和一个通知,组成成一个特殊的面。
2、AspectJ 通知类型
-
@Before:前置通知(应用:各种校验)
在方法执行前执行,如果通知抛出异常,阻止方法运行 -
@AfterReturning:后置通知(应用:常规数据处理)
方法正常返回后执行,如果方法中抛出异常,通知无法执行
必须在方法执行后才执行,所以可以获得方法的返回值。 -
@Around:环绕通知(应用:十分强大,可以做任何事情)
方法执行前后分别执行,可以阻止方法的执行
必须手动执行目标方法 -
@AfterThrowing:抛出异常通知(应用:包装异常信息)
方法抛出异常后执行,如果方法没有抛出异常,无法执行 -
@After:最终通知(应用:清理现场)
方法执行完毕后执行,无论方法中是否出现异常
3、代码示例
存在一个service实现类,作用是插入数据,代码如下:
package com.zhb.service.impl;
import com.zhb.dao.PaymentDao;
import com.zhb.entity.Payment;
import org.springframework.stereotype.Service;
import com.zhb.service.PaymentService;
import javax.annotation.Resource;
@Service
public class PaymentServiceImpl implements PaymentService
@Resource
private PaymentDao paymentDao;
@Override
public int create(Payment payment)
return paymentDao.create(payment);
3.1、@AfterReturning后置通知
@Aspect注解将PaymentAspect 声明为一个切面
@AfterReturning注解中通过returning属性指定参数的名称,用于接受目标方法的返回值。
@Aspect
@Component
public class PaymentAspect
private static final Logger logger = LoggerFactory.getLogger(PaymentAspect.class);
@AfterReturning(
returning = "result",
pointcut = "execution(* com.zhb.service.impl.PaymentServiceImpl.create(..))"
)
@SuppressWarnings("unchecked")
public Object userInsert(JoinPoint joinPoint, Object result)
//将参数转为List
//List<Object> args = Arrays.asList(joinPoint.getArgs());
Object[] args = joinPoint.getArgs();
Payment payment = null;
for (Object arg : args)
if (arg instanceof Payment)
payment = (Payment) arg;
logger.info("测试切面"+payment.getSerial());
return result;
3.2、@Around环绕通知
实现一个切面类,通过环绕通知记录方法调用详情(也可记录日志等)
package com.zhb.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class PaymentAspect
private static final Logger logger = LoggerFactory.getLogger(PaymentAspect.class);
@Around(
value = "execution(* com.zhb.service.impl.PaymentServiceImpl.create(..))"
)
@SuppressWarnings("unchecked")
public Object userInsert(ProceedingJoinPoint joinPoint)
Object result=null;
try
result= joinPoint.proceed();
logger.info("调用" + joinPoint.getTarget() + "的" + joinPoint.getSignature().getName()
+ "方法。方法返回值:" + result);
catch (Throwable e)
logger.error(joinPoint.getSignature().getName() + "方法发生异常:" + e);
finally
logger.info(joinPoint.getSignature().getName() + "方法结束执行。");
return result;
注意:此处的方法返回值是Object,以及最终的return result;
4、其他问题
4.1、多个切入点
@AfterReturning(returning = "result",
pointcut = "execution(* com.zhb.service.impl.PaymentServiceImpl.create1(..))" +
"|| execution(* com.zhb.service.impl.PaymentServiceImpl.create2(..))")
以上是关于Spring使用注解实现AOP的主要内容,如果未能解决你的问题,请参考以下文章