博客
关于我
【Spring AOP】AspectJ开发
阅读量:321 次
发布时间:2019-03-04

本文共 7278 字,大约阅读时间需要 24 分钟。


文章目录


AspectJ 开发

① AOP 操作准备 — AspectJ

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


☞ What is AspectJ?

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


☞ How to use it?

  • 基于AspectJ实现AOP操作的方式:
    • 基于xml配置文件方式
    • 基于注解方式


☞ FirstStep~

  • 在项目工程里面引入 AOP 相关依赖
    在这里插入图片描述


☞ Simple Learning

☛ 切入点表达式

     1.作用:明确对哪个类里面的哪个方法进行增强

     2.语法结构:execution( [权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )

举例 1:对 com.atguigu.dao.BookDao 类里面的 add 进行增强      execution(* com.atguigu.dao.BookDao.add(..))      举例 2:对 com.atguigu.dao.BookDao 类里面的所有的方法进行增强      execution(* com.atguigu.dao.BookDao.* (..))举例 3:对 com.atguigu.dao 包里面所有类,类里面所有方法进行增强      execution(* com.atguigu.dao.*.* (..))


② AspectJ 基于注解方式操作实现AOP

1、创建类,在类里面定义方法

package AspectJ.anno;import org.springframework.stereotype.Component;/** * 被增强的类 */public class User {       public void add(){           System.out.println("add......");    }}


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

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


3、进行通知的配置

(1)在 spring 配置文件中,开启注解扫描

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

package AspectJ.anno;import org.springframework.stereotype.Component;/** * 被增强的类 */@Component  // 添加注解创建对象public class User {       public void add(){           System.out.println("add......");    }}package AspectJ.anno;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;/** * 增强的类 */@Component // 添加注解创建对象public class UserProxy {       // 前置通知    public void before(){           System.out.println("before......");    }}

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

package AspectJ.anno;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;/** * 增强的类 */@Component // 添加注解创建对象@Aspect    // 生成代理对象public class UserProxy {       // 前置通知        public void before(){           System.out.println("before......");    }}

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


4、配置不同类型的通知

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

package AspectJ.anno;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;/** * 增强的类 */@Component // 添加注解创建对象@Aspect    // 生成代理对象public class UserProxy {       // 前置通知    // 添加前置通知注解 --- 指定切入点表达式(明确要被增强的方法)    @Before(value = "execution(* AspectJ.anno.User.add(..))")    public void before() {           System.out.println("before......");    }    //后置通知(返回通知)    @AfterReturning(value = "execution(* AspectJ.anno.User.add(..))")    public void afterReturning() {           System.out.println("afterReturning.........");    }    //最终通知    @After(value = "execution(* AspectJ.anno.User.add(..))")    public void after() {           System.out.println("after.........");    }    //异常通知    @AfterThrowing(value = "execution(* AspectJ.anno.User.add(..))")    public void afterThrowing() {           System.out.println("afterThrowing.........");    }    //环绕通知    @Around(value = "execution(* AspectJ.anno.User.add(..))")    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {           System.out.println("环绕之前.........");        //被增强的方法执行        proceedingJoinPoint.proceed();        System.out.println("环绕之后.........");    }}

注意:Around环绕通知是在被增强方法执行前、后都执行,所以被增强的方法在这之间执行,需要利用proceedingJoinPoint.proceed();来完成!!!


(2)测试

public class test {       @Test    public void test_anno(){           try {               // 加载配置文件            ApplicationContext context = new ClassPathXmlApplicationContext("AspectJ/bean_anno.xml");            // 获取对象            User user = context.getBean("user", User.class);            // 条用add方法            user.add();        } catch (Exception e){               e.printStackTrace();        }    }}

通过结果我们可以理清这五种通知的执行顺序。注意After、AfterReturing两种通知的区别,After是在被增强的方法执行后就立刻执行,AfterReturning是在返回值之后立刻执行。

在这里插入图片描述
还有AfterThrowing是在被增强的方法有异常抛出之后立即执行。可以看到在add方法中抛出异常之后,AfterThrowing执行,并且之后的所有通知均被阻断
在这里插入图片描述


5、相同的切入点抽取

比如上述的五种通知中我们使用的通知切入点表达式完全一样,针对这种情况,我们可以对其进行抽取。在类中定义一个方法(方法名称自定义),然后只需要在该方法上添加@Pointcut注解,value属性填写公共切入点表达式,然后在需要用到的注释value属性值中填写该方法名称即可

/** * 增强的类 */@Component // 添加注解创建对象@Aspect    // 生成代理对象public class UserProxy {       // 定义公共切入点抽取方法    @Pointcut(value = "execution(* AspectJ.anno.User.add(..))")    public void same_point(){       }    // 前置通知    // 添加前置通知注解 --- 指定切入点表达式(明确要被增强的方法)    @Before(value = "same_point()")    public void before() {           System.out.println("before......");    }    //后置通知(返回通知)    @AfterReturning(value = "same_point()")    public void afterReturning() {           System.out.println("afterReturning.........");    }    //最终通知    @After(value = "same_point()")    public void after() {           System.out.println("after.........");    }    //异常通知    @AfterThrowing(value = "same_point()")    public void afterThrowing() {           System.out.println("afterThrowing.........");    }    //环绕通知    @Around(value = "same_point()")    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {           System.out.println("环绕之前.........");        //被增强的方法执行        proceedingJoinPoint.proceed();        System.out.println("环绕之后.........");    }}

结果保持不变~

在这里插入图片描述


6、有多个增强类多同一个方法进行增强,设置增强类优先级

假设StudentProxy类也同时对User类中的add()方法进行增强:

  • 方法:在增强类上面添加注解 @Order(数字类型值)数字类型值越小优先级越高
package AspectJ.anno;import org.aspectj.lang.annotation.*;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;@Component@Aspect@Order(value = 1)public class StudentProxy {       @Pointcut(value = "execution(* AspectJ.anno.User.add(..))")    public void point(){       }    @Before(value = "point()")    public void before(){           System.out.println("Student Before ,........");    }    //最终通知    @After(value = "point()")    public void after() {           System.out.println("Student After.........");    }    //后置通知(返回通知)    @AfterReturning(value = "point()")    public void afterReturning() {           System.out.println("Student afterReturning.........");    }}

通过结果我们可以看出每种通知的先后执行顺序都是相对于单个增强类的内部顺序而言的当有多个类增强一个方法时,只有当级别大的(优先级低的)执行完毕后,级别小的(优先级高的)才会继续执行

在这里插入图片描述


③ AspectJ 基于xml配置文件方式操作实现AOP

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

package AspectJ.xml;/** * 被增强的类 */public class People {       public void eating(){           System.out.println("eating......");    }}package AspectJ.xml;/** * 增强类 */public class PeopleProxy {       public void before(){           System.out.println("before.......");    }}


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


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

  • 使用aop:config标签进行aop增强;
  • 之前是通过注解的方式配置切入点,在xml配置文件中,采用aop:pointcut标签来实现,其属性expression中填入切入点表达式;
  • 具体的增强方法在配置前首先要通过aop:aspect标签实现切面的配置(将通知应用到切入点的过程 — 将增强逻辑代码写入到需要增强的方法的过程),然后在切面中通过各种通知实现增强)。

在这里插入图片描述


4.测试

@Test public void test_xml(){        try {            // 加载配置文件         ApplicationContext context = new ClassPathXmlApplicationContext("AspectJ/bean_xml.xml");         // 获取对象         People people = context.getBean("people", People.class);         // 条用add方法         people.eating();     } catch (Exception e){            e.printStackTrace();     } }

通过测试运行,可以看出通过xml方式,AspectJ实现了AOP操作~

在这里插入图片描述


转载地址:http://cbeq.baihongyu.com/

你可能感兴趣的文章
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka生产者---大数据之Nifi工作笔记0036
查看>>
NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
查看>>
NIFI大数据进阶_NIFI监控功能实际操作_Summary查看系统和处理器运行情况_viewDataProvenance查看_---大数据之Nifi工作笔记0026
查看>>
NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
查看>>
NIFI大数据进阶_NIFI集群知识点_认识NIFI集群以及集群的组成部分---大数据之Nifi工作笔记0014
查看>>
NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
查看>>
NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
查看>>
NIFI大数据进阶_外部ZK模式集群1_实际操作搭建NIFI外部ZK模式集群---大数据之Nifi工作笔记0017
查看>>
NIFI大数据进阶_实时同步MySql的数据到Hive中去_可增量同步_实时监控MySql数据库变化_操作方法说明_01---大数据之Nifi工作笔记0033
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_01_实际操作---大数据之Nifi工作笔记0029
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_说明操作步骤---大数据之Nifi工作笔记0028
查看>>
NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
查看>>
NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
查看>>
NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
查看>>
NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南002---大数据之Nifi工作笔记0069
查看>>
NIFI集群_内存溢出_CPU占用100%修复_GC overhead limit exceeded_NIFI: out of memory error ---大数据之Nifi工作笔记0017
查看>>
NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061
查看>>
NIH发布包含10600张CT图像数据库 为AI算法测试铺路
查看>>
Nim教程【十二】
查看>>