Spring 的 AOP 简介

什么是 AOP

AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

AOP 是 OOP 的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

AOP 的作用及其优势

作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强

优势:减少重复代码,提高开发效率,并且便于维护

AOP 的底层实现

实际上,AOP 的底层是通过 Spring 提供的的动态代理技术实现的。在运行期间,Spring通过动态代理技术动态的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从而完成功能的增强。

AOP 相关概念

  • Target(目标对象):代理的目标对象

  • Proxy (代理):一个类被 AOP 织入增强后,就产生一个结果代理类

  • Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点

  • Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义

  • Advice(通知/ 增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知

  • Aspect(切面):是切入点和通知(引介)的结合

  • Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入

切点表达式的写法

表达式语法:

execution([修饰符] 返回值类型 包名.类名.方法名(参数))
  • 访问修饰符可以省略

  • 返回值类型、包名、类名、方法名可以使用星号* 代表任意

  • 包名与类名之间一个点 . 代表当前包下的类,两个点 … 表示当前包及其子包下的类

  • 参数列表可以使用两个点 … 表示任意个数,任意类型的参数列表

例如:

execution(public void com.itheima.aop.Target.method())
execution(void com.itheima.aop.Target.*(..))
execution(* com.itheima.aop.*.*(..))
execution(* com.itheima.aop..*.*(..))
execution(* *..*.*(..))

AOP 开发明确的事项

需要编写的内容
  • 编写核心业务代码(目标类的目标方法)

  • 编写切面类,切面类中有通知(增强功能方法)

  • 在配置文件中,配置织入关系,即将哪些通知与哪些连接点进行结合

AOP 底层使用哪种代理方式

在 spring 中,框架会根据目标类是否实现了接口来决定采用哪种动态代理的方式。

基于 XML 的 AOP 开发

①导入 AOP 相关坐标

        <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.9.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.13</version></dependency>

②创建目标接口和目标类(内部有切点)

public class ImplDao implements Dao {public void save() {System.out.println("saving");}public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Dao i = (Dao) applicationContext.getBean("target");i.save();}
}

③创建切面类(内部有增强方法)

public class MyAspect {public void before(){System.out.println("前置");}public void after(){System.out.println("后置");}public void around(ProceedingJoinPoint proceedingJoinPoint){System.out.println("环绕");try {proceedingJoinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}System.out.println("环绕");}
}

④将目标类和切面类的对象创建权交给 spring

⑤在 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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
"><bean id="aspect" class="com.MyAspect"/><bean id="target" class="com.ImplDao"/><aop:config ><aop:aspect ref="aspect"><aop:pointcut id="pc" expression="execution( void com.ImplDao.save(..))"/><aop:after method="after" pointcut-ref="pc"/><aop:before method="before" pointcut-ref="pc"/><aop:around method="around" pointcut-ref="pc"/></aop:aspect></aop:config></beans>

⑥测试代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringJunitTest {@AutowiredDao dao;@Testpublic void test(){dao.save();}
}

基于注解的 AOP 开发

基于注解的aop开发步骤:

①创建目标接口和目标类(内部有切点)

@Repository("impl")
@Scope("singleton")
public class ImplDao implements Dao {public void save() {System.out.println("saving");}public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Dao i = (Dao) applicationContext.getBean("target");i.save();}
}

②创建切面类(内部有增强方法)

@Component("aspect")
@Aspect
public class MyAspect {@Pointcut("execution( void com.ImplDao.save(..))")public void pc(){}@Before("MyAspect.pc()")public void before(){System.out.println("前置");}@After("MyAspect.pc()")public void after(){System.out.println("后置");}@Around("MyAspect.pc()")public void around(ProceedingJoinPoint proceedingJoinPoint){System.out.println("环绕");try {proceedingJoinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}System.out.println("环绕");}
}

③将目标类和切面类的对象创建权交给 spring

④在切面类中使用注解配置织入关系

⑤在配置文件中开启组件扫描和 AOP 的自动代理

<?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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
"><context:component-scan base-package="com"/><aop:aspectj-autoproxy/></beans>

⑥测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringJunitTest {@AutowiredDao dao;@Testpublic void test(){dao.save();}
}

spring—aop相关推荐

  1. Spring AOP + Redis解决重复提交的问题

    Spring AOP + Redis解决重复提交的问题 用户在点击操作的时候,可能会连续点击多次,虽然前端可以通过设置按钮的disable的属性来控制按钮不可连续点击,但是如果别人拿到请求进行模拟,依 ...

  2. 利用Spring AOP与JAVA注解为系统增加日志功能

    Spring AOP一直是Spring的一个比较有特色的功能,利用它可以在现有的代码的任何地方,嵌入我们所想的逻辑功能,并且不需要改变我们现有的代码结构. 鉴于此,现在的系统已经完成了所有的功能的开发 ...

  3. Spring AOP的一些概念

            切面(Aspect): 一个关注点的模块化,这个关注点可能会横切多个对象.事务管理是J2EE应用中一个关于横切关注点的很好的例子. 在Spring AOP中,切面可以使用通用类(基于模 ...

  4. Spring AOP与IOC

    Spring AOP实现日志服务 pom.xml需要的jar <dependency><groupId>org.apache.commons</groupId>&l ...

  5. Spring AOP与IOC以及自定义注解

    Spring AOP实现日志服务 pom.xml需要的jar <dependency><groupId>org.apache.commons</groupId>&l ...

  6. Spring Aop的应用

    2019独角兽企业重金招聘Python工程师标准>>> AOP的基本概念 连接点( Jointpoint) : 表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化.方法执行 ...

  7. Spring AOP详解(转载)所需要的包

    上一篇文章中,<Spring Aop详解(转载)>里的代码都可以运行,只是包比较多,中间缺少了几个相应的包,根据报错,几经百度搜索,终于补全了所有包. 截图如下: 在主测试类里面,有人怀疑 ...

  8. 关于spring aop Advisor排序问题

    关于spring aop Advisor排序问题 当我们使用多个Advisor的时候有时候需要排序,这时候可以用注解org.springframework.core.annotation.Order或 ...

  9. 利用spring aop统一处理异常和打日志

    利用spring aop统一处理异常和打日志 spring aop的概念,很早就写博客介绍了,现在在工作中真正使用. 我们很容易写出的代码 我们很容易写出带有很多try catch 和 logger. ...

  10. 我所理解的Spring AOP的基本概念

    Spring AOP中的概念晦涩难懂,读官方文档更是像读天书,看了很多例子后,写一些自己理解的一些spring的概念.要理解面向切面编程,要首先理解代理模式和动态代理模式. 假设一个OA系统中的一个功 ...

最新文章

  1. package main: read unexpected NUL in input
  2. 5G全球声量升级:Verizon宣布固定+移动齐步走,中国第三阶段试验倒计时
  3. 计算平方根【牛顿迭代法】
  4. OpenGL rimlight边缘照明的实例
  5. 【HDU - 1542】Atlantis (线段树,扫描线)
  6. springBoot AOP环绕增强、自定义注解、log4j2、MDC
  7. pyqt5的runJavaScript 使用模板
  8. jquery基础研究学习【基础】
  9. struts2 从一个action 跳转到另一个action的两种方法
  10. There were no servers available to complete the specified operation
  11. 怎样下载企业通讯录Excel模板
  12. AI新星丨普林斯顿陈丹琦
  13. 解决win8 64位版本下无法使用debug
  14. 计算机标准体重计算公式,项目2:就拿胖子说事---(2)计算出标准体重,当超重时,请给出提示...
  15. Flux架构思想在度咔App中的实践
  16. linux . 乱码,解决Linux乱码现象
  17. 性能追击:万字长文30+图揭秘8大主流服务器程序线程模型 | Node.js,Apache,Nginx,Netty,Redis,Tomcat,MySQL,Zuul
  18. 风之大陆 服务器不稳定,【风之大陆】7月29日更新公告
  19. 求二维向量夹角(0-360度/-180-180)及2D UI指向问题
  20. MAC下PHP开发环境教程

热门文章

  1. 【C++ Primer | 08】IO库
  2. 一条正确的Java职业生涯规划,帮你突破瓶颈
  3. linux mysql 删除表脚本_linux shell脚本自动删除mysql表前3个月的数据
  4. mysql error -1_【Mysql】SQLException: Got error -1 from storage engine 问题解决!
  5. Maven报错找不到jre
  6. linux-Centos7安装nginx
  7. Ajax请求利用jsonp实现跨域
  8. [leetcode] N-Queens II
  9. ASP .NET MVC 之Entity Framework入门教程及源码
  10. cs106a编程方法学作业解答(3)