Spring实现AOP

1、什么是 AOP

AOP (Aspect Orient Programming),直译过来就是 面向切面编程。AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。面向对象编程将程序抽象成各个层次的对象,而面向切面编程是将程序抽象成各个切面。

从该图可以很形象地看出,所谓切面,相当于应用对象间的横切点,我们可以将其单独抽象为单独的模块。

2、AOP的实现

【重要】:使用AOP需要导入依赖包

<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>

方式一:使用Spring的API接口【主要SpringAPI接口实现】

  • xml配置:

    <!--注册bean-->
    <bean id="userService" class="com.spong.demo03.UserServiceImpl"/>
    <bean id="logBefore" class="com.spong.demo03.LogBefore"/>
    <bean id="logAfter" class="com.spong.demo03.LogAfter"/> <!--方式一: 使用原生的Spring API接口-->
    <!--配置aop:需要导入aop的约束-->
    <aop:config>
    切入点:expression:表达式,execution(要执行的位置: * * * ...)
    <aop:pointcut id="pointcut" expression="execution(* com.spong.demo03.UserServiceImpl.*(..))"/> <!--执行环绕增加-->
    <aop:advisor advice-ref="logAfter" pointcut-ref="pointcut"/>
    <aop:advisor advice-ref="logBefore" pointcut-ref="pointcut"/>
    </aop:config>
  • 需要切入的类(实现aop包下的接口MethodBeforeAdvice、AfterReturningAdvice等)

    public class LogBefore implements MethodBeforeAdvice {
    
        /**
    *
    * @param method 要执行的目标对象的方法
    * @param objects 方法参数
    * @param o 目标对象
    * @throws Throwable
    */
    public void before(Method method, Object[] objects, Object o) throws Throwable {
    System.out.println(o.getClass().getName()+"的"+method.getName()+"执行");
    }
    }
    public class LogAfter implements AfterReturningAdvice {
    
        /**
    *
    * @param returnValue 方法执行后的返回值
    * @param method
    * @param args
    * @param target
    * @throws Throwable
    */
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
    System.out.println(target.getClass().getName()+"的"+method.getName()+"方法执行,返回值为"+returnValue);
    }
    }

方式二:自定义类来实现AOP【主要是切面定义】

  • 自定义类:

    public class Diy {
    
        public void logBefore(){
    System.out.println("方法执行前");
    } public void logAfter(){
    System.out.println("方法执行后");
    }
    }
  • xml配置:

    <!--方式二: 自定义类-->
    <bean id="diy" class="com.spong.demo03.Diy"/> <aop:config>
    <aop:aspect ref="diy">
    <aop:pointcut id="pointcut" expression="execution(* com.spong.demo03.UserServiceImpl.*(..))"/>
    <aop:before method="logBefore" pointcut-ref="pointcut"/>
    <aop:after method="logAfter" pointcut-ref="pointcut"/>
    </aop:aspect>
    </aop:config>

方式三:使用注解实现

  • 使用注解实现的切面类:

    //使用注解实现AOP
    @Aspect //标注为一个切面
    @Component //注入bean
    public class AnnotationPointCut { //设置切入点
    @Pointcut("execution(* com.spong.demo03.UserServiceImpl.*(..))")
    private void pointCut(){} @Before("pointCut()")
    public void logBefore(){
    System.out.println("方法执行前");
    } @After("pointCut()")
    public void logAfter(){
    System.out.println("方法执行后");
    } @Around("pointCut()") //环绕增强,我们可以给定一个参数,代表我们要获取处理切入的点;
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("环绕前");
    System.out.println(joinPoint.getSignature()); //获得签名(调用了哪个类的哪个方法)
    Object proceed = joinPoint.proceed();
    System.out.println("环绕后");
    } }
  • xml配置:

    <!--开启aop注解支持-->
    <aop:aspectj-autoproxy/> <!--开启注解支持-->
    <context:component-scan base-package="com.spong.demo03"/>
    <context:annotation-config></context:annotation-config>
  • 测试类

    public class MyTest {
    public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    //这里返回的是一个代理类实例,代理类也是实现了UserService接口
    UserService userService = context.getBean("userService", UserService.class);
    userService.add();
    }
    }
  • 测试结果:

    环绕前
    void com.spong.demo03.UserService.add()
    方法执行前
    add
    方法执行后
    环绕后

切入点表达式execution (* com.sample.service..*. *(..))解析:

整个表达式可以分为五个部分:

1、execution()::表达式主体。

2、第一个*号:表示返回类型, *号表示所有的类型。

3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service包、子孙包下所有类的方法。

4、第二个号:表示类名,号表示所有的类。

5、(..):最后这个星号表示方法名,号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数

Spring——AOP实现的更多相关文章

  1. 学习AOP之深入一点Spring Aop

    上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...

  2. 学习AOP之认识一下Spring AOP

    心碎之事 要说知道AOP这个词倒是很久很久以前了,但是直到今天我也不敢说非常的理解它,其中的各种概念即抽象又太拗口. 在几次面试中都被问及AOP,但是真的没有答上来,或者都在面上,这给面试官的感觉就是 ...

  3. spring aop

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将 ...

  4. spring aop注解方式与xml方式配置

    注解方式 applicationContext.xml 加入下面配置 <!--Spring Aop 启用自动代理注解 --> <aop:aspectj-autoproxy proxy ...

  5. 基于Spring AOP的JDK动态代理和CGLIB代理

    一.AOP的概念  在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...

  6. Spring AOP详解

    一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...

  7. Spring AOP实例——异常处理和记录程序执行时间

    实例简介: 这个实例主要用于在一个系统的所有方法执行过程中出线异常时,把异常信息都记录下来,另外记录每个方法的执行时间. 用两个业务逻辑来说明上述功能,这两个业务逻辑首先使用Spring AOP的自动 ...

  8. 从零开始学 Java - Spring AOP 实现用户权限验证

    每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...

  9. 从零开始学 Java - Spring AOP 实现主从读写分离

    深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...

  10. 从零开始学 Java - Spring AOP 拦截器的基本实现

    一个程序猿在梦中解决的 Bug 没有人是不做梦的,在所有梦的排行中,白日梦最令人伤感.不知道身为程序猿的大家,有没有睡了一觉,然后在梦中把睡之前代码中怎么也搞不定的 Bug 给解决的经历?反正我是有过 ...

随机推荐

  1. 【管理员已阻止你运行此应用】windows defender图标打叉,无法打开mmc.exe解决办法

    今天开机遇到一个奇怪的问题,发现windows defender图标上面打了个×: 打开按照系统提示需要restart服务,但是无法重启服务,会出现错误,然后尝试手动重启服务,准备打开管理控制台mmc ...

  2. js原声代码 轮播图

    js轮播图 html部分:建立div,内嵌img标签,可以设置大小, <!doctype html> <html> <head> <meta charset= ...

  3. SpringBoot学习之整合Druid的简单应用

    一.Druid介绍 Druid简介 Druid是目前Java语言中最好的数据库连接池之一.结合了 C3P0.DBCP 等 DB 池的优点,同时加入了日志监控.Druid 是一个分布式的.支持实时多维 ...

  4. 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...

  5. SAP四代增强实现:销售订单复制项目文本时不需要显示文本框和回车

    最近接收到一个业务需求,在SAP依据销售订单复制时,如果订单里面的项目有多个文本,系统就会显示复制的文本框处理,让用户选择是否复制,这个就让销售很不舒服,如果有几十个项目,每个项目有几个文本,那就就要 ...

  6. 线程_multiprocessing实现文件夹copy器

    import multiprocessing import os import time import random def copy_file(queue,file_name,source_fold ...

  7. Python File writelines() 方法

    概述 writelines() 方法用于向文件中写入一序列的字符串.高佣联盟 www.cgewang.com 这一序列字符串可以是由迭代对象产生的,如一个字符串列表. 换行需要制定换行符 \n. 语法 ...

  8. PHP uasort() 函数

    ------------恢复内容开始------------ 实例 使用用户自定义的比较函数对数组 $arr 中的元素按键值进行排序: <?phpfunction my_sort($a,$b){ ...

  9. luogu P3409 值日班长值周班长 exgcd

    LINK:值日班长值周班长 题目描述非常垃圾. 题意:一周5天 每周有一个值周班长 每天有一个值日班长 值日班长日换 值周班长周换. 共n个值日班长 m个值周班长 A是第p个值日班长 B是第q个值日班 ...

  10. 4.2 省选模拟赛 旅行路线 广义SAM

    \(n\leq 100000\) 题目上求出 多少条本质不同的路线. 首先定义了 相似的城市为度数相同的城市. 还定义了两条路线相同当且仅当长度相同 且对应位置的城市都是相似的. 考虑这张图的形态 n ...