AOP 操作

news/2024/9/22 16:53:40/

AOP 操作

  • AOP 操作(准备)
    • 1. Spring 框架一般是基于 AspectJ 实现 AOP 操作
      • (1)什么是 AspectJ
    • 2. 基于 AspectJ 实现 AOP 操作
    • 3. 在项目工程里面引入 AOP 先关的依赖
    • 4. 切入点表达式
      • 举例1:对 com.fairykunkun.dao.UserDao 类里面的 add 进行增强
      • 举例2:对 com.fairykunkun.dao.UserDao 类里面的所有方法进行增强
      • 举例3:对 com.fairykunkun.dao 包里面的所有类的所有方法进行增强
  • AOP 操作( Aspect 注解)
    • 1. 创建一个类,在类里面定义方法
    • 2. 创建增强类(编写增强逻辑)
      • (1)在增强类里面,创建方法,让不同的方法代表不同的通知类型
    • 3. 进行通知的一个配置
      • (1)在 Spring 的配置文件中开启注解的扫描
      • (2)使用注解创建 User 和 UserProxy 对象
      • (3)在增强类上面添加注解 @Aspect
      • (4)在 Spring 配置文件中开启生成代理对象
    • 4. 配置不同类型的通知
      • (1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
      • 5. 测试
      • 6. 总结
      • 7. 公共(相同)切入点抽取
      • 8. 多个增强类对我们的同一个方法进行增强,设置增强类的优先级
      • 9. 完全使用注解开发
  • AOP 操作( AspectJ 配置文件)
    • 1. 创建两个类,增强类和被增强类,创建方法
    • 2. 在 Spring 配置文件中创建两个类对象
    • 3. 在 Spring 配置文件中配置切入点

AOP 操作(准备)

1. Spring 框架一般是基于 AspectJ 实现 AOP 操作

(1)什么是 AspectJ

AspectJ 不是 Spring 组成部分,独立 AOP 框架,一般把 AspectJ 和 Spring 框架一起使用,进行 AOP 操作

2. 基于 AspectJ 实现 AOP 操作

(1)基于 xml 配置文件实现
(2)基于注解的方式实现

3. 在项目工程里面引入 AOP 先关的依赖

<!--aop相关依赖-->
<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.3.20</version>
</dependency>
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.9.9.1</version>
</dependency>
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.9.1</version>
</dependency>
<dependency><groupId>org.assertj</groupId><artifactId>assertj-core</artifactId><version>3.23.1</version>
</dependency>

4. 切入点表达式

(1)切入点表达式的作用:知道对哪个类里面的那个方法进行增强
(2)语法结构

execution([权限修饰符][返回类型][全类名][方法名称]([参数列表]))

举例1:对 com.fairykunkun.dao.UserDao 类里面的 add 进行增强

execution(*com.fairykunkun.dao.UserDao.add(..))

举例2:对 com.fairykunkun.dao.UserDao 类里面的所有方法进行增强

execution(*com.fairykunkun.dao.UserDao.*(..))

举例3:对 com.fairykunkun.dao 包里面的所有类的所有方法进行增强

execution(*com.fairykunkun.dao.*.*(..))

AOP 操作( Aspect 注解)

1. 创建一个类,在类里面定义方法

package com.fairykunkun.aopanno;
// 被增强的类
public class User {public void add ( ) {System.out.println ( "add ..." );}
}

2. 创建增强类(编写增强逻辑)

(1)在增强类里面,创建方法,让不同的方法代表不同的通知类型

package com.fairykunkun.aopanno;
// 增强的类
public class UserProxy {public void before ( ) {// 前置通知System.out.println ( "before ..." );}
}

3. 进行通知的一个配置

(1)在 Spring 的配置文件中开启注解的扫描

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 开启注解的扫描 --><context:component-scan base-package = "com.fairykunkun.aopanno"></context:component-scan>
</beans>

(2)使用注解创建 User 和 UserProxy 对象

package com.fairykunkun.aopanno;
import org.springframework.stereotype.Component;
// 被增强的类
@Component
public class User {public void add ( ) {System.out.println ( "add ..." );}
}
package com.fairykunkun.aopanno;
import org.springframework.stereotype.Component;
// 增强的类
@Component
public class UserProxy {// 前置通知public void before ( ) {System.out.println ( "before ..." );}
}

(3)在增强类上面添加注解 @Aspect

package com.fairykunkun.aopanno;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {// 前置通知public void before ( ) {System.out.println ( "before ..." );}
}

(4)在 Spring 配置文件中开启生成代理对象

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 开启注解的扫描 --><context:component-scan base-package = "com.fairykunkun.aopanno"></context:component-scan><!-- 开启 Aspect生成代理对象 --><aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

4. 配置不同类型的通知

(1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置

package com.fairykunkun.aopanno;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {// 前置通知// @Before 注解表示作为前置通知// * 表示可以返回任意值@Before ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )public void before ( ) {System.out.println ( "before ..." );}
}

5. 测试

package com.fairykunkun;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.fairykunkun.aopanno.User;
public class TestAop {@Testpublic void testAopAno ( ) {ApplicationContext context =new ClassPathXmlApplicationContext ( "bean11.xml" );User user = context.getBean ( "user" , User.class );user.add ( );}
}

实验结果

  • 继续完善增强类的方法
package com.fairykunkun.aopanno;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {// 前置通知// @Before 注解表示作为前置通知// * 表示可以返回任意值@Before ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )public void before ( ) {System.out.println ( "before ..." );}@AfterThrowing ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )public void afterThrowing ( ) {System.out.println ( "afterThrowing......" );}@After ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )public void after ( ) {System.out.println ( "after......" );}	// 环绕通知@Around ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )public void around ( ProceedingJoinPoint proceedingJoinPoint ) throws Throwable {System.out.println ( "环绕之前......" );// 被增强的方法执行proceedingJoinPoint.proceed ( );System.out.println ( "环绕之后......" );}
}
  • 再看一下测试结果
package com.fairykunkun.aopanno;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {// 前置通知// @Before 注解表示作为前置通知// * 表示可以返回任意值@Before ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )public void before ( ) {System.out.println ( "before ..." );}@AfterThrowing ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )public void afterThrowing ( ) {System.out.println ( "afterThrowing......" );}@AfterReturning ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )public void afterReturning ( ) {System.out.println ( "afterReturning......" );}@After ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )public void after ( ) {System.out.println ( "after......" );}// 环绕通知@Around ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )public void around ( ProceedingJoinPoint proceedingJoinPoint ) throws Throwable {System.out.println ( "环绕之前......" );// 被增强的方法执行proceedingJoinPoint.proceed ( );System.out.println ( "环绕之后......" );}
}
  • 看一下实验结果
    在这里插入图片描述
  • 在 User 的 add 方法中模拟一个异常
package com.fairykunkun.aopanno;
import org.springframework.stereotype.Component;
// 被增强的类
@Component
public class User {public void add ( ) {int i=10/0;System.out.println ( "add ..." );}
}
  • 测试
    测试结果

6. 总结

  • @Before(前置通知)
  • @AfterReturning(后置通知,返回通知)
  • @After(最终通知)
  • @Around(环绕通知)
  • @AfterThrowing(异常通知)

7. 公共(相同)切入点抽取

package com.fairykunkun.aopanno;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {// 相同切入点抽取@Pointcut ( value = "execution(* com.fairykunkun.aopanno.User.add(..))" )public void pointdemo ( ) {}// 前置通知// @Before 注解表示作为前置通知// * 表示可以返回任意值@Before ( value = "pointdemo()" )public void before ( ) {System.out.println ( "before ..." );}@AfterThrowing ( value = "pointdemo()" )public void afterThrowing ( ) {System.out.println ( "afterThrowing......" );}@AfterReturning ( value = "pointdemo()" )public void afterReturning ( ) {System.out.println ( "afterReturning......" );}@After ( value = "pointdemo()" )public void after ( ) {System.out.println ( "after......" );}// 环绕通知@Around ( value = "pointdemo()" )public void around ( ProceedingJoinPoint proceedingJoinPoint ) throws Throwable {System.out.println ( "环绕之前......" );// 被增强的方法执行proceedingJoinPoint.proceed ( );System.out.println ( "环绕之后......" );}
}
  • 把之前做的那个异常去掉,然后再做测试
    实验结果图

8. 多个增强类对我们的同一个方法进行增强,设置增强类的优先级

package com.fairykunkun.aopanno;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class PersonProxy {// 前置通知@Before  (value = "execution(* com.fairykunkun.aopanno.User.add(..))")public void before() {System.out.println ("Person Before......" );}
}

(1)在增强类上面添加注解@Order(数字类型值),数字类型值越小优先级越高

package com.fairykunkun.aopanno;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Aspect
@Order(1)
public class PersonProxy {// 前置通知@Before  (value = "execution(* com.fairykunkun.aopanno.User.add(..))")public void before() {System.out.println ("Person Before......" );}
}
  • 测试
    测试结果

9. 完全使用注解开发

(1)创建配置类,不需要创建 xml 配置文件

package com.fairykunkun.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan ( basePackages = { "com.fairykunkun" } )
@EnableAspectJAutoProxy ( proxyTargetClass = true )
public class AopConfig {
}

AOP 操作( AspectJ 配置文件)

1. 创建两个类,增强类和被增强类,创建方法

package com.fairykunkun.aopxml;
public class Book {public void buy ( ) {System.out.println ( "buy" );}
}
package com.fairykunkun.aopxml;
public class BookProxy {public void before ( ) {System.out.println ( "before......" );}
}

2. 在 Spring 配置文件中创建两个类对象

<?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"xsi:schemaLocation = "http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 创建对象 --><bean id = "book" class = "com.fairykunkun.aopxml.Book"></bean><bean id = "bookProxy" class = "com.fairykunkun.aopxml.BookProxy"></bean>
</beans>

3. 在 Spring 配置文件中配置切入点

<?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"xsi:schemaLocation = "http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 创建对象 --><bean id = "book" class = "com.fairykunkun.aopxml.Book"></bean><bean id = "bookProxy" class = "com.fairykunkun.aopxml.BookProxy"></bean><!-- 配置 aop 增强 --><aop:config><!-- 切入点 --><aop:pointcut id = "p" expression = "execution(* com.fairykunkun.aopxml.Book.buy(..))"/><!-- 配置切面 --><aop:aspect ref = "bookProxy"><!-- 增强作用在具体的方法上 --><aop:before method = "before" pointcut-ref = "p"/></aop:aspect></aop:config>
</beans>
  • 测试
package com.fairykunkun;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.fairykunkun.aopxml.Book;
public class TestAop {@Testpublic void testAopXml ( ) {ApplicationContext context =new ClassPathXmlApplicationContext ( "bean12.xml" );Book book = context.getBean ( "book" , Book.class );book.buy ( );}
}

测试结果


http://www.ppmy.cn/news/4576.html

相关文章

Qt之天气预报——界面优化篇(含源码+注释)

一、界面优化效果 下方为界面优化完成和优化前的效果对比。 优化前&#xff1a; 优化后&#xff1a; 二、优化内容 添加标题栏添加图片&#xff08;图图标素材源自阿里巴巴矢量图标库&#xff09;更新UI内容&#xff08;微调大小、布局比例&#xff09;添加鼠标事件函数&…

校园兼职网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 网站前台&#xff1a;关于我们、联系我们、资讯信息、企业信息、职位信息 管理员模块&#xff1a; 1、管理关于我们、联…

18.Django大型项目之用户中心页面

1. 用户中心的搭建 1.1 基础搭建 这里&#xff0c;主要就是基础的页面渲染&#xff0c;使用的也是继承主模板&#xff0c;对其进行修改的方式。就直接看代码吧 1.2 上下文的应用 什么是上下文&#xff1f; 对于上下文&#xff0c;可以理解成一个公用的函数或者类 我们这里使…

make 报错 *** recipe commences before first target. Stop.

背景 学习linux设备驱动&#xff0c;写第一个hello world程序&#xff0c;make报错&#xff1a; edenubuntu:~/Documents/Project/scull/hello_world$ make Makefile:17: *** recipe commences before first target. Stop. 原因 最后查明原因是我的target多了tab Makefile的…

[山东科技大学OJ]2622 Problem I: 数组元素计数 (Append Code)

Time Limit: 1 Sec Memory Limit: 2 MB Submit: 1032 Solved: 782 [Submit][Status] Description 输出一个数组中与指定数字相同的元素的个数。 ----------------------------------------------------------------------------- 结合“Append Code”中的代码&#xff0c;编…

uboot启动流程

目录 1. 从汇编到C语言 1. 从汇编到C语言 uboot整个程序的入口是 ./arch/arm/lib/vectors.S 的 start 其中&#xff0c;reset 来自于 ./arch/arm/cpu/armv7/start.S&#xff0c; ./arch/arm/cpu/armv7/start.S 程序的执行路径为 reset --> save_boot_params_ret --> cp…

Java集合/泛型面试题

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java面试题…

1. Scss 基础使用

1. Scss 基础使用 1. 语法格式 Sass 有两种语法格式。首先是 SCSS (Sassy CSS) &#xff0c;这种格式仅在 CSS3 语法的基础上进行拓展&#xff0c;所有 CSS3 语法在 SCSS 中都是通用的&#xff0c;同时加入 Sass 的特色功能。此外&#xff0c;SCSS 也支持大多数 CSS hacks 写…