栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring使用注解实现AOP

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring使用注解实现AOP

1、AOP术语
    target:目标类,需要被代理的类。Joinpoint(连接点):所谓连接点是指那些可能被拦截到的方法。例如:所有的方法PointCut 切入点:已经被增强的连接点。例如:某个增强的方法advice 通知/增强:增强代码。例如:after、beforeWeaving(织入):是指把增强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) {
        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;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/703806.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号