AOP切面编程

AOP切面编程


  • AOP概述
  • AOP的相关名词
  • AOP的两种配置

一.AOP概述


1.AOP,也就是面向切面编程。同时也是一种思想,可在不改变程序源码的情况下为程序添加额外的功能。

2.AOP的意图

允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发。应用对象只实现业务逻辑即可,而不负责其它的系统级关注点,从而达到降低代码之间的耦合度,图解如下:

图一:业务对象与系统服务(日志,安全,事务)过于紧密,每一个业务除了要关注自己的业务,还要亲自执行一些日志,进行安全控制和参与事务,导致代码高耦合度。

图二:应用AOP切面,使这些与业务无关的逻辑模块化,以声明的方式应用到需要影响的组件上,让业务组件具有更高的内聚性以及更好的关注自身的业务,不用涉及到一些日志,系统服务带来的复杂性,从而达到降低代码之间的耦合度。

3.AOP的实现原理

主要的实现原理:通过动态代理(也就是代理模式,代理模式的定义:给某一个对象提供一个代理,并由代理对象控制对原对象的引用),在不修改源代码快的前提下,添加不同方法逻辑或通知,通过两种代理实现:

  1. 利用cglib工具包

目标对象没有实现接口使用CGLIB代理。

  1. 利用 JDK Proxy API

如果目标对象实现接口,使用JDK代理。JDK动态代理特点:

2.1.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们提供目标对象所实现的接口的字节码对象)

2.2.动态代理要求目标对象一定要实现接口,所以也叫做接口代理。

二.AOP的相关名词


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S34QUDJl-1599971248825)(C:\Users\damo\AppData\Roaming\Typora\typora-user-images\image-20200826192634610.png)]

  1. 连接点(Join point)

    连接点就是程序执行过程中能够插入的一个点,这个点可以是调用方法时或修改一个字段时,切面代码可以通过这个点插入到程序中,并可以添加新的行为。

  2. 切点(Poincut)

    切点的定义:会匹配通知所要织入得一个或多个连接点,在应用中可以通过明确的包名+类名,或方法名称来指定哪些切点。

    <!--
    作用在方法上的表达式execution([修饰符] 返回值类型 包名.类名.方法名(参数))
    修饰符:可以省略
    返回类型:*代表任意返回值
    包名.类名:com.damo.service.*代表service包下的任意类
    包名.类名.方法名(参数):com.damo.service.*.*(..)代表service包下的任意类的任意方法,(..)方法上的参数(不管方法是否有参)
    -->
    <aop:pointcut id="pointcut" expression="execution(* com.damo.service.*.*(..))" />
    <!--within(包名.类名)-->
    <aop:pointcut id="pointcut" expression="within(com.damo.service.*))" />
    

    连接点和切点的区别:连接点是满足切点扫描条件的时机点,决定哪些可以成为切点。(例子:一层楼的所有出口都是连接点,我们选择具体那个出口出去才是切点)

  3. 通知(Advice)

    通知的定义:切面的工作就是通知,用于定义切面是什么时候使用和切面需要完成的工作。Spring切面可以应用到5种类型的通知:

    • 前置通知(Before):目标方法被调用前调用通知功能
    • 后置通知/最终通知(After):目标方法被调用后调用通知功能,无论方法输出返回什么
    • 返回通知(After-returning):目标方法成功执行后调用通知
    • 异常通知(After-throwing):目标方法抛出异常后调用通知
    • 环绕通知(Around):在目标方法执行前后之间调用通知
  4. 切面(Aspect)

    切面的定义:就是需要进行的切面内容,需要进行什么逻辑处理之类的内容。

  5. 织入

    织入是把切面应用到目标对象并创建新的代理的过程,这个过程可以发生在编译器、类转载期、运行期。

<!--spring的aop编程 的织入功能-->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aspects</artifactId>
	<version>5.2.3.RELEASE</version>
</dependency>

三.AOP的配置


AOP的配置方式主要有两种方式:

  1. XML配置
<!--AOP配置-->
<aop:config>
    	<!--
			设置切点
            id:切点名称
            expression:切点表达式
        -->
        <aop:pointcut id="pointcut" expression="within(com.damo.service.*))" />
        <aop:aspect ref="log">
            <!--
			method:设置某个方法为切面逻辑方法
			pointcut-ref:切点对象ID
			returing:方法返回值传给切面
			throwing:异常对象传给切面处理
			-->
            <!--前置通知-->
            <aop:before method="before" pointcut-ref="pointcut" />
            <!--后置通知-->
            <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="a" />
            <!--最终通知-->
            <aop:after method="after" pointcut-ref="pointcut" />
            <!--环绕通知-->
            <aop:around method="around" pointcut-ref="pointcut" />
            <!--异常通知-->
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e" />
    	</aop:aspect>
</aop:config>
  1. 纯注解方式
//标注为配置类
@Configuration
//开启包扫描
@ComponentScan(basePackages = "com.mlz")
//首先在配置类中开启AOP注解主持
@EnableAspectJAutoProxy
public class SpringConfig {}
@Component  //spring容器管理bean
@Aspect  //标记为切面组件类
public class LogAspect {

    //@Pointcut设置切入点表达式注解
    //设置连接点是类
    //@Pointcut("within(cn..*Impl)")
    //设置连接点是方法
    @Pointcut("execution(* cn..*Impl.*(..))")
    public void pointcut(){};

    /**
     * 方法执行前的切面方法
     * @Before  替代前置通知标签aop-before
     */
    @Before("pointcut()")
    public void before(){
        System.out.println("方法执行前,记录日志..........");
    }

    //返回后通知
    @AfterReturning(pointcut = "pointcut()",returning = "obj")
    public void afterReturning(Object obj){
        System.out.println("方法执行返回后,记录日志..........");
    }

    //最终通知,不管是否有异常都会执行
    @After("pointcut()")
    public void after(){
        System.out.println("方法执行后,最终通知,记录日志..........");
    }

    //异常通知
    @AfterThrowing(pointcut = "pointcut()",throwing = "e")
    public void afterThrowing(Exception e){
        System.out.println("方法执行发生异常,异常通知记录日志..........");
    }

    /**
     * ProceedingJoinPoint:封装了Method对象的连接点
     * @param joinPoint
     */
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕通知前置记录日志...............");

        Object proceed = joinPoint.proceed();//执行目标方法的逻辑

        System.out.println("环绕通知后置记录日志................");
        return proceed;//目标方法返回值
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP切面编程是一种通过配置的方式,实现在Spring开发中的AOP功能。切面由切点和增强组成,切点用于定义在哪些连接点上应用增强,而增强指的是在连接点上要执行的逻辑操作。SpringAOP强大之处在于不需要通过代码,只需要使用注解或XML配置就可以完成相同的功能。 在学习Spring开发的AOP面向切面编程时,需要导入相应的jar包,例如com.springsource.net.sf.cglib-2.2.0.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar。切面编程是一种实现横切关注点的重用和集中管理的技术,它可以让我们更加方便地实现一些横切关注点,如日志记录、事务管理等,并将其与业务逻辑分离开来,提高代码的复用性和可维护性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [spring AOP切面编程](https://blog.csdn.net/weixin_43525993/article/details/107902045)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [SpringAOP切面编程依赖jar包.rar](https://download.csdn.net/download/weixin_44888416/12374630)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值