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

SpringAOP面向切面编程

一、概念

Spring AOP(Aspect-Oriented Programming,面向切面编程)是 Spring 框架的核心特性之一,本质是通过预编译和运行期动态代理,在不修改原有代码的前提下,为程序添加统一功能(如日志、事务、权限校验)的技术。

假如我100个方法,此时我想给这100个方法都添加日志。我难道要重新编写这100种方法的源码吗?这太麻烦了。SpringAOP提供了一种新的方向,即通过xml配置文件或注解的方式在指定方法前后运行增强方法。

SpringAOP的设级思想不仅降低了代码的运行复杂性,还减少了代码之间的耦合度。大大增强了代码的可读性和可维护性。

二、AOP术语

名称代指
1、连接点当前类中哪个方法可以被增强,这些方法称为连接点
2、切入点实际增强的方法
3、增强(通知)实际增加的逻辑部分
4、切面将通知应用到切入点的过程

通知的类型:

1、前置通知(before)方法执行前执行
2、后置通知(after-returning)方法执行后执行
3、环绕通知(around)方法执行前后都会执行
4、最终通知(after)无论方法执行是否成功,最终都会执行
5、异常通知(after-throwing)发生异常时执行

 

三、基于动态代理的实现机制

“需要被增强的方法” 对应 目标对象(Target) 的核心业务方法(比如 Service 里的业务逻辑)。

“增强方法(power)” 对应 切面(Aspect) 里的通用功能(比如日志、事务的逻辑)。

“动态代理公司” 是 Spring 底层的动态代理机制(JDK 或 CGLIB),它负责把“增强方法”和“需要被增强的方法”结合起来。

最终生成的“代理对象”对外提供服务,当调用“执行代理方法”时,会先执行“增强方法”的逻辑,再执行原业务方法的逻辑(或根据通知类型调整执行顺序)。

四、xml配置文件形式实现

1.在maven包中导入AOP的依赖:

  <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency>
<!--单元测试--><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!--AOP联盟(接口规范)--><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><!--Spring Aspects(springAOP实现)--><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.0.2.RELEASE</version></dependency><!--aspectj实现面向切面的核心--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.3</version></dependency></dependencies>

2.配置切面:

    <!--将user映射为bean对象--><bean id="user" class="com.newFile.User"></bean><bean id="power" class="com.notice.Power"></bean><!--配置切面--><aop:config><!--配置切面 = 切入点 + 通知组成--><!--由哪一个bean承担切面通知(增强类)逻辑--><aop:aspect ref="power"><!--判断是那种情况,再执行那种增强方法,是那个方法执行时调用的--><aop:after-throwing method="afterThrowing" pointcut="execution(public void com.newFile.User.add())"/></aop:aspect></aop:config>

1.ref="power"表示增强类。

2.method表示增强类中的哪个增强方法。

3.pointcut:后边是执行哪个切入点方法,作用是知道对切面的哪个方法进行增强。

4.aop:表示通知类型。

后续只需要在power类中写增强方法,在User类中写被增强方法(例如前面提到的那100种方法)即可。

五、注解形式实现

1.开启注解扫描、注解形式实现AOP:

<!--使用注解实现-->
<!--扫描com包下所有文件(开启注解扫描)--><context:component-scan base-package="com"></context:component-scan>
<!--启动注解方式实现SpringAOP--><aop:aspectj-autoproxy></aop:aspectj-autoproxy>

aop:aspectj-autoproxy

“aop:aspectj-autoproxy”的核心作用是:让 Spring 自动识别被  @Aspect  注解标记的“切面类”,并为匹配“切入点”的目标对象动态生成代理对象,从而使“通知逻辑”(如日志、权限校验)能自动织入到目标方法的执行流程中。

简单来说,“aop:aspectj-autoproxy”是基于注解方式实现的“开关”,有了它,你在代码中通过  @Aspect 、 @Before 、 @Pointcut  等注解编写的切面逻辑才能生效。

2.在增强类和切入类添加@Component,将普通的类标注为Spring的管理组件(相当于Bean,默认id为类名首字母小写),再在增强类上标注@Aspect表示增强类。

增强类:

//component将普通的类标注为Spring容器管理的Bean类
//Controller表示控制层
//Service表示服务层
//Repository表示持久层
//后三者均为Component的的特殊化形式
@Component
//Aspect表示增强类
@Aspect
public class Power {//前置通知@Before(value = "execution(public void com.newFile.User.add())")//让before在add执行前执行//在xml中完成AOP的设置public void beforeaa(){System.out.println("before........");}public void beforebb(){System.out.println("xxxxxx........");}// 环绕通知  入参代表的是切入点@Around(value = "execution(public void com.newFile.User.add())")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("before.............around1");//  执行被增强的方法(由配置文件配置)proceedingJoinPoint.proceed();System.out.println("after.............around2");}// 最终通知@After(value = "execution(public void com.newFile.User.add())")public void after() {System.out.println("after.............");}//后置通知@AfterReturning(value = "execution(public void com.newFile.User.add())")public void afterReturning() {System.out.println("afterReturning.............");}//异常通知@AfterThrowing(value = "execution(public void com.newFile.User.add())")public void afterThrowing() {System.out.println("afterThrowing.............");}
}

execution(public void com.newFile.User.add())表示执行类路径下的哪个切入点时调用此通知方法。

http://www.dtcms.com/a/414574.html

相关文章:

  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(36):文法運用
  • 郑州做网站茂睿科技全域seo
  • 一阶谓词逻辑及其重要子集对人工智能自然语言处理深层语义分析的影响与启示
  • 平阴县网站建设视频直播网站开发与制作
  • GPTEngineer:AI 驱动的Web应用开发平台
  • STL简介
  • 本地安装Codex,国内直接使用GPT-5-Codex
  • OpenGL ES vs VG-Lite:嵌入式图形渲染引擎对比分析
  • Linux 自定义shell命令解释器
  • 陕西科强建设工程有限公司官方网站重庆企业建站系统模板
  • 【RabbitMQ】原理解析
  • Spring的IoC与DI
  • 做家装的网站有哪些安徽建工集团网站
  • 零知IDE——基于STM32F407VET6和雨滴传感器的多界面TFT降雨监测显示系统
  • 轻松在家构建AI集群,开启智能生活
  • 从PHP入门到公网部署:Web开发与服务器运维实战指南
  • 产品展示网站系统深圳app搭建
  • 40 dubbo和springcloud
  • (26)ASP.NET Core2.2 EF保存(基本保存、保存相关数据、级联删除、使用事务)
  • 西昌新站seo太原网站建设方案开发
  • 永久个人网站网站开发 设计文档
  • 天拓四方集团IoT平台在金属表面处理行业的智能化转型实践
  • 00-1-正则表达式学习心得:从入门到上瘾,再到克制
  • 【性能测试之正则表达式】正则表达式零基础入门:从“抄”到“写”,附性能测试实战案例
  • python-poppler - PDF文档处理Python绑定库
  • Android开发-Handler消息机制记录
  • 通信专业知识图谱​
  • 网站建设的页面要求一级域名二级域名
  • 基础镜像清理策略在VPS环境存储优化中的维护规范
  • The 2025 ICPC South America - Brazil First Phase