您的位置:首页 > 健康 > 养生 > Spring-2- AOP 切面编程

Spring-2- AOP 切面编程

2024/10/5 18:29:41 来源:https://blog.csdn.net/m0_75138009/article/details/141475992  浏览:    关键词:Spring-2- AOP 切面编程

当我们需要对一个类中的方法进行功能的增强,又不想改变原方法的代码时

当我们需要保护一个类中的代码时

我们都可以使用代理模式,帮助这个类完成一些功能,这就是 AOP 切面编程

核心:切面 = 通知 + 切点

首先,需要引入 AOP 要用到的切面

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.breeze</groupId><artifactId>aspect</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><!--仓库--><repositories><!--spring里程碑版本的仓库--><repository><id>repository.spring.milestone</id><name>Spring Milestone Repository</name><url>https://repo.spring.io/milestone</url></repository></repositories><!--依赖--><dependencies><!--spring context--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.0-M2</version></dependency><!--spring aspects--><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>6.0.0-M2</version></dependency><!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties></project>

spring.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--包扫描--><context:component-scan base-package="all"/>
<!--    要写上这一行才能开启动态代理,使用 AOP--><aop:aspectj-autoproxy/></beans>

编写 需要被增强 的目标类方法

@Component("first")
public class First {//原始方法,称作目标方法public void origin(){System.out.println("我是原始方法");}}

编写代理方法

@Component
@Aspect
public class Plus {//增强原始方法,称之为代理方法@Before("execution(public * all.First.*(..))")//引号中的就是切点,以切点表达式的方式找到原始方法public void add(){System.out.println("在原始方法执行前,增强了一些功能");}}

@Before 就是通知,@Before 里面的参数就是切点。合起来就是切面

通知

常用通知:

@Before 目标方向执行前

@AfterReturning 目标方法执行后

@Around 前后都添加
eg:
@Around("execution(public * dao.Orcle.*(..))")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {//传参连接点,固定参数
        System.out.println("----------------------------");//前环绕
        joinPoint.proceed();//执行目标,固定方法
        System.out.println("----------------------------");//后环绕
    }

@AfterThrowing 发生异常时添加

@After  放在 finally 语句块的最终通知

叠加通知的作用顺序:
前环绕
前置
原本的方法被执行了
后置
最终通知
后环绕

异常通知在最终通知之后,在异常通知之后的后环绕不会执行

切点

常用切点表达式:

一、基于方法执行的切点表达式


匹配特定方法名称
execution(* com.example.service.UserService.findUserById(..)):匹配 com.example.service.UserService 类中名为 findUserById 的方法,无论其参数类型是什么。


匹配特定包下的所有方法
execution(* com.example.service.*.*(..)):匹配 com.example.service 包下任意类的任意方法。


匹配特定返回类型的方法
execution(* com.example.service.UserService.getUser(..)) && return-type=com.example.domain.User:匹配 com.example.service.UserService 类中名为 getUser 且返回类型为 com.example.domain.User 的方法。


二、基于类的切点表达式


匹配特定类中的所有方法
within(com.example.service.UserService):匹配 com.example.service.UserService 类中的所有方法。


匹配特定包下的所有类的所有方法
within(com.example.service.*):匹配 com.example.service 包下所有类的所有方法。


三、基于注解的切点表达式


匹配带有特定注解的方法
@annotation(com.example.annotation.Loggable):匹配带有 @com.example.annotation.Loggable 注解的方法。


四、基于目标对象的切点表达式


匹配特定类型的目标对象的所有方法调用
target(com.example.domain.User):匹配目标对象为 com.example.domain.User 类型的所有方法调用。

切面叠加

当多个切面作用于一个目标方法时
可以通过 @Order(n) 排序
n 越小优先级越高
不论优先级怎样,前置通知一定在目标发放前就被执行,后置通知同理

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com