在前两篇博客中,介绍了AOP实现的基础:静态代理和动态代理,这篇博客介绍spring中AOP的实现。

一、采用Annotation方式

首先引入jar包:aspectjrt.jar && aspectweaver.jar

applicationContext配置文件:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><?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"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"><!-- 启用AspectJ对Annotation的支持 -->       <span style="color:#ff0000;"><aop:aspectj-autoproxy/></span>           <bean id="user" class="com.angel.spring.User"/><bean id="successfulHandler" class="com.angel.spring.SuccessfulHandler"/></beans>
</span>

接口和实现类省略

代理拦截类:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;@Aspect
public class SuccessfulHandler {/*** 定义Pointcut,Pointcut的名称为addAddMethod(),此方法没有返回值和参数* 该方法就是一个标识,不进行调用*/@Pointcut("execution(* add*(..))")private void addAddMethod(){};/*** 定义Advice,表示我们的Advice应用到哪些Pointcut订阅的Joinpoint上*///@Before("addAddMethod()")@After("addAddMethod()")private void checkSecurity() {System.out.println("-------Angel,方法执行成功!-------");}
}
</span>

通过以上的配置,就可以实现对于方法调用的拦截。我们使用的注解有@Aspect,标记此类是一个横切面的插入类(拦截类),然后使用@Pointcut,标记我们的拦截方法需要作用于那些地方,最后使用@Before或者@After标记我们的拦截方法是作用于被调用方法前或者后。

但是,通过注解的方式,我们就需要为每个方法都添加注解,如果要修改的话,还得逐一修改,这样子,虽然同样轻便,但是如果有一个地方统一配置AOP的话,那就会更为简便,接下来,我们看第二种实现方式:采用配置方式

二、采用配置方式

applicationContext的配置:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><?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"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"><!-- 启用AspectJ对Annotation的支持 --><!-- <aop:aspectj-autoproxy/> --><bean id="user" class="com.angel.spring.User" /><bean id="successfulHandler" class="com.angel.spring.SuccessfulHandler" /><aop:config><aop:aspect id="IsSuccessfulAspect" ref="successfulHandler"><!-- com.bjpowernode.spring包下所有的类所有的方法<aop:pointcut id="addAddMethod" expression="execution(* com.bjpowernode.spring.*.*(..))"/> --><!-- com.bjpowernode.spring包下所有的类的以add和del开头的方法--><aop:pointcut id="addAddMethod" expression="execution(* com.angel.spring.*.add*(..)) || execution(* com.angel.spring.*.del*(..))" /><aop:before method="checkSecurity" pointcut-ref="addAddMethod" /></aop:aspect></aop:config></beans>
</span>

拦截类:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;import org.aspectj.lang.JoinPoint;public class SuccessfulHandler {private void checkSecurity(JoinPoint joinPoint) {System.out.println("-------Angel,方法执行成功!-------");}
}</span>

经过这样的配置就可以实现方法的拦截了,但有时候,我们不仅需要拦截方法名称,我们还需要知道,在执行这个方法的时候,用户到底传递了什么样的参数,那么,我们需要在拦截类采用Advice中添加一个JoinPoint参数,取得客户端调用的方法名称及参数值,如:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.spring;import org.aspectj.lang.JoinPoint;public class SuccessfulHandler {private void checkSecurity(JoinPoint joinPoint) {for (int i=0; i<joinPoint.getArgs().length; i++) {System.out.println(joinPoint.getArgs()[i]);}System.out.println(joinPoint.getSignature().getName());System.out.println("-------Angel,方法执行成功!-------");}
}</span>

三、采用CGLIB代理

以上的例子,我们都是采用JDK的代理实现的AOP,JDK的动态代理是代理的接口,如果有些类并没有实现接口,那么我们将不得不采用另外一种代理方式:CGLIB动态代理。如:

首先,引入支撑CGLIB的jar包cglib-nodep.jar

其次,在applicationContext配置文件中,强制开启CGLIB代理:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><!-- 强制使用CGLIB代理 -->
<aop:aspectj-autoproxy proxy-target-class="true" /></span>

区别:User类不再实现IUser接口,而是一个单独的类,代理成功!

四、总结

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

对于AOP的总结,到此结束,接下来总结事务的知识点。PS:深刻感觉,之前对于AOP是被吓退了!

转载于:https://www.cnblogs.com/hhx626/p/6010307.html

【spring 5】AOP:spring中对于AOP的的实现相关推荐

  1. 一文读懂Spring中的AOP机制

    一.前言 这一篇我们来说一下 Spring 中的 AOP 机制,为啥说完注解的原理然后又要说 AOP 机制呢? 1.标记日志打印的自定义注解 @Target({ElementType.METHOD}) ...

  2. Spring中的AOP在Advice方法中获取目标方法的参

    参考:http://my.oschina.net/itblog/blog/211693 http://christang.iteye.com/blog/2037919 http://blog.csdn ...

  3. spring中关于aop拦截功能的记录

    java写了个接口并写了个实现类: package myspring.calculator; public interface IArithmeticCalculator { public doubl ...

  4. 动态代理——》AOP —— Spring 中的 AOP||AOP 相关术语||学习 spring 中的 AOP 要明确的事

    AOP 概述 什么是 AOP       AOP:全称是 Aspect Oriented Programming 即:面向切面编程 AOP 的作用及优势 作用: 在程序运行期间,不修改源码对已有方法进 ...

  5. Spring Boot中使用AOP统一处理Web请求日志

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是Spring框架中的一个重要内容,它通 ...

  6. Spring中的AOP(三)——基于Annotation的配置方式(一)

    为什么80%的码农都做不了架构师?>>>    AspectJ允许使用注解用于定义切面.切入点和增强处理,而Spring框架则可以识别并根据这些注解来生成AOP代理.Spring只是 ...

  7. spring中的aop术语和细节

    Spring中AOP的细节 说明 我们学习spring的aop,就是通过配置的方式 AOP相关术语 Joinpoint(连接点): 所谓连接点是指那些被拦截到的点.在spring中,这些点指的是方法, ...

  8. 手动实现SPring中的AOP(1)

    Spring中的AOP是基于JDK的API动态的在内存中创建代理对象的.所以这里先介绍一些设计模式之----代理模式: a)         代理模式的定义:代理(Proxy)模式是一种提供对目标对象 ...

  9. redis spring 切面缓存_今日份学习: Spring中使用AOP并实现redis缓存?

    笔记 在Spring中如何使用AOP? Spring是如何切换JDK动态代理和CGLIB的? spring.aop.proxy-target-class=true (在下方第二个链接中,原生doc中提 ...

最新文章

  1. 使用C#创建SQLite控制台应用程序
  2. containerd 与安全沙箱的 Kubernetes 初体验
  3. 标签页如何用php静态显示,php使用标签替换的方式生成静态页面
  4. how is sales pipeline retrieved from backend
  5. android 自定义wifi设置在哪里,Android Wifi的设置、连接操作
  6. jQuery动画与事件概念以及语法
  7. 采用合适的网站优化技术
  8. 有时候能讲出来,比沉默要好吧
  9. [算法] 已知前序和后序遍历,建立二叉树
  10. Day38 python基础--并发编程基础-IO模型
  11. 1146 Topological Order(25 分)
  12. 以字型为例,一维表示的二维数组矩阵,旋转90、-90
  13. C语言实现SM4加解密
  14. hive 求两个月之间的时间间隔(月留存)
  15. 创建阻止windows自动锁屏的脚本
  16. QEMU-KVM设备热插拔机制简析
  17. Redhat下小企鹅输入法的安装
  18. Geforce 错误代码 ERROR CODE:0x0003问题方法
  19. No4.搭建基本的授权码模式请求token(一):实现授权服务端的授权码模式操作
  20. SQL-按日期不间断统计

热门文章

  1. intval0.57100 php_php中0,'',null,false,true,FLASE,TREU,array()的相等恒等学习
  2. π是无理数证明定积分_证明圆周率是无理数很容易?人类花了2000年!
  3. 武汉大学计算机学院放假时间,计算机学院关于2019年学生放暑假的通知
  4. linux 文件拷贝并替换,Linux_cmd replace 文件替换使用说明,帮助信息: 复制代码 代码如 - phpStudy...
  5. mysql运维工资_MySQL运维踩坑
  6. python语言入门r_小结:jieba分词的Python与R语言基础用法介绍
  7. 0基础小白学好JAVA的5个方法
  8. 使用Python和OpenCV构建图像金字塔
  9. 使用 Inception-v3,实现图像识别(Python、C++)
  10. 使用回调函数实现图像阈值分析。程序运行后在屏幕中输入阈值,通过改变滑动条实现不同类型的二值化图。