当前位置: 首页 > article >正文

【Spring】Spring Aop基础入门

一、AOP(Aspect-Oriented Programming: 面向切面编程)

        将那些与业务无关,却为业务模块所共同调用的逻辑(例如事务处理、日志管理、权限控制等)封装抽取成一个可重用的模块,这个模块被命名为“切面”(Aspect),便于减少系统的重复代码降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

二、Spring AOP 基于动态代理实现

        如果被代理的对象,已经实现某个接口,则 Spring AOP 会使用 JDK Proxy(反射),基于接口的方式,创建代理对象(JDK动态代理的核心InvocationHandler接口Proxy);

         如果被代理的对象,没有实现某个接口,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 Cglib,基于继承的方式,生成一个被代理对象的子类来作为代理(Cglib动态代理的核心MethodInterceptor接口Enhancer类);

三、AOP通知类型

        AOP将抽取出来的共性功能称为通知;

        通知类型:以通知在上下文中的具体位置作为划分

                前置通知(Before)

                返回通知(After-returning)

                异常通知(After-throwing)

                后置通知(After)

                环绕通知(Around)

        AOP连接点(Join point):AOP将所有的方法都视为连接点,不管是接口里面的抽象方法,还是实现类里面的重写方法,都是连接点。

        AOP切点(Pointcut):AOP将可能被抽取共性功能的方法称为切入点。切入点是连接点的子集

        AOP目标对象(Target):就是挖掉功能的方法对应的类生的对象,这种对象是无法直接完成最终工作的。

        AOP织入(Weaving):就是将挖掉的功能回填的动态过程。

        AOP切面切点+通知

四、SpringAOP+AspectJ实现步骤

(1)pom.xml中添加依赖,aop与aspectj表达式的依赖

        

(2)创建spring的主配置文件,bean内的命名空间要添加aop的

(3)创建业务代码并编写日志记录代码(事务管理代码)

(4)将业务层与日志记录层注入spring容器

(5)<aop:config>--aop配置

           aop:aspect--aop切面:     <aop:aspect id="" ref="通知类">

             aop:pointcut--aop切点:   <aop:pointcut id="" expression="execution(业务方法)"/>

                通知内容通知类型:

                <aop:before method="通知类方法名(前置通知)" pointcut-ref="切点id"/>

                <aop:after-returning method="通知类方法名(返回通知)" pointcut-ref="切点id"/>

                <aop:after-throwing method="通知类方法名(异常通知)" pointcut-ref="切点id"/>

                <aop:after method="通知类方法名(后置通知)" pointcut-ref="切点id"/>

                <aop:around method="通知类方法名(环绕通知)" pointcut-ref="切点id"/>

        切点表达式配置语法

        execution(修饰符 返回值 包名称.类名称.方法名称(参数列表))

        eg: execution(public void com.apesource.service.ServiceImp.findAll())

    (1)修饰符可以省略代表任意

                execution(返回值 包名称.类名称.方法名称(参数列表))

    (2)返回值可以使用“*”代表任意

                execution(* 包名称.类名称.方法名称(参数列表))

    (3)包名可以使用“*”代表任意名称

                execution(* *.*.*.类名称.方法名称(参数列表))

    (4)包名可以使用“..”代表任意个数

                execution(* *...类名称.方法名称(参数列表))

    (5)类名与方法名可以使用“*”代表任意

                execution(* *...*.*(参数列表))

    (6)参数列表可以使用".."代表任意个数任意类型

                execution(* *...*.*(..))

                如果有参数:

                    基本类型:int======>int

                    引用类型:String===>java.lang.String

        主配置文件:applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">


    <!-- 注入业务层 -->
    <bean id="service" class="com.apesource.service.AccountServiceImp"></bean>

    <!-- 注入日志记录层(通知) -->
    <bean id="logger" class="com.apesource.util.Logger"></bean>

    <!-- 配置AOP -->
    <aop:config>
        <!-- 配置切面  -->
        <aop:aspect id="aopAspect" ref="logger">
            <!-- 切点 -->
            <aop:pointcut id="dian" expression="execution(public void com.apesource.service.AccountServiceImp.*(..))"/>
<!--            <aop:pointcut id="dian" expression="execution(* com.apesource.service.*.*(..))"/>-->

            <!-- 通知 -->
            <aop:before method="beforeMethod" pointcut-ref="dian"/>
            <aop:after-returning method="returnMethod" pointcut-ref="dian"/>
            <aop:after-throwing method="throwMethod" pointcut-ref="dian"/>
            <aop:after method="afterMethod" pointcut-ref="dian"/>

            <aop:around method="arroundMethod" pointcut-ref="dian"/>
        </aop:aspect>
    </aop:config>


</beans>


http://www.kler.cn/a/322336.html

相关文章:

  • 小鹏汽车大数据面试题及参考答案
  • [代码随想录Day16打卡] 找树左下角的值 路径总和 从中序与后序遍历序列构造二叉树
  • 【JavaEE初阶 — 多线程】定时器的应用及模拟实现
  • urdf笔记
  • js实现导航栏鼠标移入时,下划线跟随鼠标滑动
  • 【GNU】gcc -g编译选项 -g0 -g1 -g2 -g3 -gdwarf
  • QML使用Qt自带软键盘例子
  • 深度学习-图像处理篇1.1-1.2神经网络
  • 【Prometheus】实战二:Prometheus数据监控自定义组件Pushgateway
  • Day101 代码随想录打卡|动态规划篇--- 分割等和子集
  • 帆软通过JavaScript注入sql,实现数据动态查询
  • [Linux#55][网络协议] 序列化与反序列化 | TcpCalculate为例
  • 微信小程序加载H5页面及与H5页面通信的实战教程
  • 代码随想录算法训练营 | 二叉树理论基础
  • 【python】函数的定义
  • 简历技能面试问答
  • MySQL InnoDB MVCC数据结构分析
  • 基于Hadoop的NBA球员大数据分析及可视化系统
  • Splashtop 在2024年 CybersecAsia 读者之选奖项评选中荣获新星奖
  • 【Vue】以RuoYi框架前端为例,ElementUI封装图片上传组件——将图片信息转成base64后提交到后端保存
  • opengauss使用遇到的问题,随时更新
  • android 页面布局(1)
  • 从git删除/上传新的文件-简单命令菜鸟教程
  • 常用并发设计模式精讲
  • Unity八股总结
  • java在开发中的总结