Spring AOP简介

如果说IOC是Spring的核心,那么面向切面编程就是Spring最核心的功能之一了,在数据库事务中,面向切面编程被广泛应用。

AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码降低模块间的耦合度,并有利于未来的可拓展性和可维护性

面向切面编程

在OOP中,是面向对象开发,开发流程大致如下:

面向切面编程,关注的是切面,相当于在自上而下的流程中横插进去,这种方式的好处就是对代码的侵入性小,不会影响原有的实现业务。

Spring AOP名词介绍

在理解时,一定要先搞清楚AOP部分名词的含义,这样可以让你更好理解。

官方英文文档:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#aop

其中:

  • Aspect

切面,一种开发思想,很好地例子就是事务管理。

  • Join Point

程序执行过程中的一点,例如方法的执行或异常的处理。

  • Advice

通知,可以表示在执行点前、后或者前后执行的一种状态。

  • Pointcut

切入点,表示在执行到某一个状态或标志时(具体可表示某一方法、注解或类等),执行切面增强的方法。

  • Introduction

代表类型声明其他方法或字段。

  • Target object

目标对象,即为原始切入的对象。

  • AOP proxy

增强对象方法后的代理对象,在AOP中,使用的是JDK或CGLIB动态代理,此proxy即为动态代理生成的对象。

  • Weaving

织入,运行时为增强方法后的对象生成代理对象。

使用注解开发Sping AOP

需求说明:用AOP实现日志记录功能,需要记录方法实现时间。

分析图:

Maven项目引入所需包:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>

项目目录:

首先写一个业务方法:

package com.yl.service;

import org.springframework.stereotype.Service;

@Service
public class DemoService { public void doMethod() {
System.out.println("调用Service方法");
}
}

定义切面:

  • execution表达式

基本语法

execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)  除了返回类型模式、方法名模式和参数模式外,其它项都是可选的。

execution(* com.yl.service...(..))

符号 含义
execution() 表达式主体
第一个“*”符号 表示任何类型的返回值
com.yl.service 表示业务类的包路径
“..”符号 表示当前包及子包
第二个“*“符号 表示所有类
“.*(..)” 表示任何方法名,(..)表示任意参数
package com.yl.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component; // 将类声明成IOC中的bean
@Component
// 声明这是一个切面
@Aspect
public class DemoAspect { /**
* 定义切入点
*/
@Pointcut("execution(* com.yl.service..*.*(..))")
public void servicePointcut() { } /**
* 后置通知
*/
@After("servicePointcut()")
public void doAfter() {
System.out.println("执行后置方法");
} /**
* 前置通知
*/
@Before("servicePointcut()")
public void doBefore() {
System.out.println("执行前置方法");
} /**
* 环绕通知
* @throws Throwable
*/
@Around("servicePointcut()")
public void doAdvice(ProceedingJoinPoint joinPoint){
long start = System.currentTimeMillis();
try {
// 执行被切入方法
joinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
long stop = System.currentTimeMillis();
long time = stop - start;
System.out.println("执行时长:" + time);
}
}

配置开启AOP自动代理,包扫描路径:

package com.yl.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration
@ComponentScan("com.yl") // 包扫描路径,表示需要扫描到IOC中的bean的路径
@EnableAspectJAutoProxy // 默认使用JDK代理,将proxyTargetClass传为true则为使用CGLIB代理
public class ProjectConfig { }

启动类:

package com.yl;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.yl.config.ProjectConfig;
import com.yl.service.DemoService; public class Test {
public static void main(String[] args) {
@SuppressWarnings("resource")
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProjectConfig.class);
DemoService demoService = context.getBean(DemoService.class);
demoService.doMethod();
}
}

运行结果:

执行前置方法
调用Service方法
执行时长:15
执行后置方法

此程序利用AOP面向切面编程的思想,实现了基本的日志记录功能,更多功能可以通过Spring官网或其他途径继续了解。

如果您对AOP的JDK、CGLIB动态代理感兴趣,请移步《关于Java代理那些事儿》

理解Spring AOP的实现方式与思想的更多相关文章

  1. spring 理解Spring AOP 一个简单的约定游戏

    应该说AOP原理是Spring技术中最难理解的一个部分,而这个约定游戏也许会给你很多的帮助,通过这个约定游戏,就可以理解Spring AOP的含义和实现方法,也能帮助读者更好地运用Spring AOP ...

  2. spring aop 使用注解方式总结

    spring aop的注解方式:和xml的配置方式略有区别,详细如下: 1.首先还是建立需要的切面类:切面类里面定义好切点配置,以及所有的需要实现的通知方法. /** * */ package com ...

  3. 深入理解Spring AOP之二代理对象生成

    深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 ...

  4. Spring AOP 不同配置方式产生的冲突问题

    Spring AOP的原理是 JDK 动态代理和CGLIB字节码增强技术,前者需要被代理类实现相应接口,也只有接口中的方法可以被JDK动态代理技术所处理:后者实际上是生成一个子类,来覆盖被代理类,那么 ...

  5. 深入理解Spring AOP思想

    什么是AOP?AOP解决了什么问题? 在传统的开发模式中,以下层次的是非常常见的一种,业务层每一个方法都要有重复的事务代码 如何改善这个问题? AOP希望将A.B 这些分散在各个业务逻辑中的相同代码, ...

  6. 轻松理解 Spring AOP

    目录 Spring AOP 简介 Spring AOP 的基本概念 面向切面编程 AOP 的目的 AOP 术语和流程 术语 流程 五大通知执行顺序 例子 图例 实际的代码 使用 Spring AOP ...

  7. 【Spring AOP】Spring AOP的使用方式【Q】

    Spring AOP的三种使用方式 经典AOP使用方式 改进XML配置方式 基于注解的方式 第1种方式可以作为理解spring配置AOP的基础,是最原始的配置方式,也体现了spring处理的过程. 使 ...

  8. Spring AOP(二)--注解方式

    本文介绍通过注解@AspectJ实现Spring AOP,这里要重点说明一下这种方式实现时所需的包,因为Aspect是第三方提供的,不包含在spring中,所以不能只导入spring-aop的包,为了 ...

  9. 曹工说Spring Boot源码(21)-- 为了让大家理解Spring Aop利器ProxyFactory,我已经拼了

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

随机推荐

  1. C#设计模式之21-策略模式

    策略模式(Stragety Pattern) 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/427 访问. 策略模式属于 ...

  2. Homekit_Dohome_月球灯

    此款月球灯可以使用Homekit或者Dohome App进行有效的智能控制,支持多种色彩和亮度调节,功能强大,有兴趣的可以去以下链接看看: https://item.taobao.com/item.h ...

  3. golang 字符型

    目录 前言 1. 基本 介绍 2. 声明 3. 使用细节 4. 字符类型的本质 跳转 前言 不做文字的搬运工,多做灵感性记录 这是平时学习总结的地方,用做知识库 平时看到其他文章的相关知识,也会增加到 ...

  4. 封装react antd的表格table组件

    封装组件是为了能在开发过程中高度复用功能和样式相似的组件,以便我们只关注于业务逻辑层的处理,提高开发效率,提高逼格,降低代码重复率,降低劳动时间,减少加班的可能. 本次组件的封装采用了函数式组件即无状 ...

  5. 报错:Cause: java.sql.SQLSyntaxErrorException: ORA-00936: 缺失表达式

    错误原因:

  6. 使用IDEA新建基于SpringBoot的Web项目(超详细)

    目前java的开发很多Learner都慢慢的学习使用IDEA这款工具,个人觉得其实相比Eclipse来说差不多,个人习惯的问题,但是我还是推荐IDEA这款工具.虽然它目前是收费的,但相信网上的各种破解 ...

  7. 笔记:Ubuntu安装LAMP环境

    一.更换Ubuntu的镜像源 镜像源路径:/etc/apt/sources.list 备份:cp /etc/apt/sources.list /etc/apt/souces.list.bak 使用阿里 ...

  8. Ubuntu图形桌面切换到命令行界面

    Ubuntu提供两种进入方式,一个是我们平常最熟悉的图形界面形式,还有一种是纯命令行方式. 1.按 Ctrl + Alt + (F1~F6中的任意一个)即可进入纯命令行模式. 进入后,需要输入用户名, ...

  9. echars 饼图使用

    option = {       tooltip: {         trigger: 'item',         formatter: '{a} <br/>{b}: {c} ({d ...

  10. 测试和发布说明(Alpha版本)

    Alpha版本测试报告 1.测试中发现的BUG 已修复  服务器无法发送邮件 重复上传同一首歌曲 下载进度无法实时跟进 可以多次点击上传 注册验证码失真 上传结束无法及时清理队列信息 不可重现的BUG ...