前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java架构笔记——Spring AOP的实现方式

Java架构笔记——Spring AOP的实现方式

作者头像
慕容千语
发布2019-06-11 23:36:17
5570
发布2019-06-11 23:36:17
举报

spring aop的实现方式

  • 基于xml配置的spring aop
  • 基于注解配置的aop

AOP常用的实现方式有两种,一种是采用声明的方式来实现(基于XML),一种是采用注解的方式来实现(基于AspectJ)。

首先复习下AOP中一些比较重要的概念: Joinpoint(连接点):程序执行时的某个特定的点,在Spring中就是某一个方法的执行 。

Pointcut(切点):说的通俗点,spring中AOP的切点就是指一些方法的集合,而这些方法是需要被增强、被代理的。一般都是按照一定的约定规则来表示的,如正则表达式等。切点是由一类连接点组成。

Advice(通知):还是说的通俗点,就是在指定切点上要干些什么。

Advisor(通知器):其实就是切点和通知的结合 。

一、基于XML配置的Spring AOP

采用声明的方式实现(在XML文件中配置),大致步骤为:配置文件中配置pointcut, 在java中用编写实际的aspect 类, 针对对切入点进行相关的业务处理。

切面类:

代码语言:javascript
复制
package com.spring.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class AopAspect {
    /**
     * 前置通知:目标方法调用之前执行的代码
     * @param jp
     */
    public void doBefore( JoinPoint jp )
    {
        System.out.println( "===========执行前置通知============" );
    }
    /**
     * 后置返回通知:目标方法正常结束后执行的代码
     * 返回通知是可以访问到目标方法的返回值的
     * @param jp
     * @param result
     */
    public void doAfterReturning( JoinPoint jp, String result )
    {
        System.out.println( "===========执行后置通知============" );
        System.out.println( "返回值result===================" + result );
    }
    /**
     * 最终通知:目标方法调用之后执行的代码(无论目标方法是否出现异常均执行)
     * 因为方法可能会出现异常,所以不能返回方法的返回值
     * @param jp
     */
    public void doAfter( JoinPoint jp )
    {
        System.out.println( "===========执行最终通知============" );
    }
    /**
     *
     * 异常通知:目标方法抛出异常时执行的代码
     * 可以访问到异常对象
     * @param jp
     * @param ex
     */
    public void doAfterThrowing( JoinPoint jp, Exception ex )
    {
        System.out.println( "===========执行异常通知============" );
    }
    /**
     * 环绕通知:目标方法调用前后执行的代码,可以在方法调用前后完成自定义的行为。
     * 包围一个连接点(join point)的通知。它会在切入点方法执行前执行同时方法结束也会执行对应的部分。
     * 主要是调用proceed()方法来执行切入点方法,来作为环绕通知前后方法的分水岭。
     *
     * 环绕通知类似于动态代理的全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法。
     * 而且环绕通知必须有返回值,返回值即为目标方法的返回值
     * @param pjp
     * @return
     * @throws Throwable
     */
    public Object doAround( ProceedingJoinPoint pjp ) throws Throwable
    {
        System.out.println( "======执行环绕通知开始=========" );
        /* 调用方法的参数 */
        Object[] args = pjp.getArgs();
        /* 调用的方法名 */
        String method = pjp.getSignature().getName();
        /* 获取目标对象 */
        Object target = pjp.getTarget();
        /*
         * 执行完方法的返回值
         * 调用proceed()方法,就会触发切入点方法执行
         */
        Object result = pjp.proceed();
        System.out.println( "输出,方法名:" + method + ";目标对象:" + target + ";返回值:" + result );
        System.out.println( "======执行环绕通知结束=========" );
        return(result);
    }
}
代码语言:javascript
复制
 <?xml version="1.0"?>
 
 <bean id="aspectBean" class="com.spring.aop.AopAspect" />
 <aop:config>
 <aop:aspect ref="aspectBean">
 <aop:pointcut id="pointcut" expression="execution(* com.spring.service.impl.UserManagerServiceImpl..*(..))" />
 <aop:before method="doBefore" pointcut-ref="pointcut" />
 <aop:after-returning method="doAfterReturning" pointcut-ref="pointcut" returning="result" />
 <aop:after method="doAfter" pointcut-ref="pointcut" />
 <aop:around method="doAround" pointcut-ref="pointcut" />
 <aop:after-throwing method="doAfterThrowing" pointcut-ref="pointcut" throwing="ex" />
 </aop:aspect>
 </aop:config>
 

二、基于注解配置的aop:

代码语言:javascript
复制
<!-- 声明spring对@AspectJ的支持 -->
 <aop:aspectj-autoproxy/> 
@Aspect
public class AopAspectJ {
    /**
     * 必须为final String类型的,注解里要使用的变量只能是静态常量类型的
     */
    public static final String EDP = "execution(* com.spring.service.impl.UserManagerServiceImpl..*(..))";
    /**
     * 切面的前置方法 即方法执行前拦截到的方法
     * 在目标方法执行之前的通知
     * @param jp
     */
    @Before( EDP )
    public void doBefore( JoinPoint jp )
    {
        System.out.println( "=========执行前置通知==========" );
    }
    /**
     * 在方法正常执行通过之后执行的通知叫做返回通知
     * 可以返回到方法的返回值 在注解后加入returning
     * @param jp
     * @param result
     */
    @AfterReturning( value = EDP, returning = "result" )
    public void doAfterReturning( JoinPoint jp, String result )
    {
        System.out.println( "===========执行后置通知============" );
    }
    /**
     * 最终通知:目标方法调用之后执行的通知(无论目标方法是否出现异常均执行)
     * @param jp
     */
    @After( value = EDP )
    public void doAfter( JoinPoint jp )
    {
        System.out.println( "===========执行最终通知============" );
    }
    /**
     * 环绕通知:目标方法调用前后执行的通知,可以在方法调用前后完成自定义的行为。
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around( EDP )
    public Object doAround( ProceedingJoinPoint pjp ) throws Throwable
    {
        System.out.println( "======执行环绕通知开始=========" );
        /* 调用方法的参数 */
        Object[] args = pjp.getArgs();
        /* 调用的方法名 */
        String method = pjp.getSignature().getName();
        /* 获取目标对象 */
        Object target = pjp.getTarget();
        /*
         * 执行完方法的返回值
         * 调用proceed()方法,就会触发切入点方法执行
         */
        Object result = pjp.proceed();
        System.out.println( "输出,方法名:" + method + ";目标对象:" + target + ";返回值:" + result );
        System.out.println( "======执行环绕通知结束=========" );
        return(result);
    }
    /**
     * 在目标方法非正常执行完成, 抛出异常的时候会走此方法
     * @param jp
     * @param ex
     */
    @AfterThrowing( value = EDP, throwing = "ex" )
    public void doAfterThrowing( JoinPoint jp, Exception ex )
    {
        System.out.println( "===========执行异常通知============" );
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.03.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • spring aop的实现方式
  • 一、基于XML配置的Spring AOP
  • 二、基于注解配置的aop:
相关产品与服务
云顾问
云顾问(Tencent Cloud Smart Advisor)是一款提供可视化云架构IDE和多个ITOM领域垂直应用的云上治理平台,以“一个平台,多个应用”为产品理念,依托腾讯云海量运维专家经验,助您打造卓越架构,实现便捷、灵活的一站式云上治理。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档