1、概念

(1)AspectJ是一个基于Java语言的AOP框架

(2)Spring2.0以后新增了对AspectJ切入点表达式的支持

(3)AspectJ是AspectJ1.5的新增功能,通过JDK5注解技术,允许在Bean类中定义切面。新版本的Spring框架建议使用AspectJ方式来开发AOP

2、切入点表达式

(1)execution():用语描述方法

语法:execution(修饰符、返回值、包、类、方法(参数)、异常)

修饰符:一般省略

public:公共方法

*:任意

返回值

void:没有返回值

String:返回值为字符串

*:返回值任意

方法:不能省略

参数

(..)参数任意

(2)案例:

  1. <aop:pointcut id="myPointCut" expression="execution(* pers.zhb.proxy.*.*(..))"></aop:pointcut>

(3)其他表达式

within:匹配包或者子包中的方法

this:匹配接口中代理对象中的方法

target:匹配实现接口的目标对象的方法

args:匹配参数格式符合标准的方法

bean:对指定bean所有的方法

2、AspectJ通知类型

(1)aop联盟定义通知类型:具有特性接口,必须实现,从而确定方法名称。
(2)aspectj通知类型:只定义类型名称。已经方法格式。
before:前置通知(应用:各种校验)

在方法执行前执行,如果通知抛出异常,阻止方法运行

afterRetuming:后置通知(应用:常规数据处理)

方法正常返回后执行,如果方法中抛出异常,通知无法执行

必须在方法执行后才执行,所以可以获得方法的返回值

around:环统通知(应用:十分强大,可以做任何事情)

方法执行前后分别执行,可以阻止方法的执行。
必须手动执行目标方法

afterThrowing:抛出异常通知(应用:包装异常信息)

方法抛出异常后执行,如果方法没有抛出异常,无法执行

after最终通知(应用:清理现场)

方法执行完毕后执行,无论方法中是否出现异常

3、导入jar包(四个)

aop联盟规范

spring aop实现

aspect规范

spring aspect实现

4、源码

(1)AspectJAfterThrowingAdvice

(2)AspectJAfterAdvice

5、基于XML文件的配置(前置通知)

(1)目标类的接口和实现类:

  1. public interface StudentService {
  2. void addStudent();
  3. void updateStudent();
  4. void deleteStudent();
  5. }
  1. public class StudentServiceImpl implements StudentService {
  2. @Override
  3. public void addStudent() {
  4. System.out.println("addStudent");
  5. }
  6.  
  7. @Override
  8. public void updateStudent() {
  9. System.out.println("updateStudent");
  10. }
  11.  
  12. @Override
  13. public void deleteStudent() {
  14. System.out.println("deleteStudent");
  15. }
  16. }

(2)切面类(含有通知):

  1. public class MyAspect {
  2. public void before(JoinPoint joinPoint){
  3. System.out.println("前置通知:"+ joinPoint.getSignature().getName());
  4. }
  5. }

(3)配置文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns="http://www.springframework.org/schema/beans"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/aop
  8. http://www.springframework.org/schema/aop/spring-aop.xsd">
  9. <!--目标类-->
  10. <bean id="studentService" class="pers.zhb.aspectxml.StudentServiceImpl"></bean>
  11. <!--切面类-->
  12. <bean id="myAspect" class="pers.zhb.aspectxml.MyAspect"></bean>
  13. <!--aop编程
  14. 将切面类声明为切面,从而获得通知(方法)
  15. ref:切面类引用
  16. -->
  17. <aop:config>
  18. <aop:aspect ref="myAspect">
  19. <!--引入切面类,从中获得通知(方法)
  20. expression:切入点表达式
  21. id:名称,用于其他通知引用
  22. -->
  23. <aop:pointcut id="myPointCut" expression="execution(* pers.zhb.aspectxml.StudentServiceImpl.*(..))"></aop:pointcut>
  24. <!--
  25. method:通知,即方法名
  26. pointcut:切入点表达式,此表达式只能当前通知使用
  27. pointcut-ref:切入点的引用,可以和其它通知共享切入点
  28. -->
  29. <aop:before method="before" pointcut-ref="myPointCut"></aop:before>
  30. </aop:aspect>
  31. </aop:config>
  32. </beans>

(4)测试类:

  1. public class TestAspectXml {
  2. public static void main(String[] args) {
  3. ApplicationContext applicationContext=new
  4. ClassPathXmlApplicationContext("applicationContext.xml");
  5. //获得目标类
  6. pers.zhb.aspectxml.StudentService studentService= (StudentService) applicationContext.getBean("studentService");
  7. studentService.addStudent();
  8. studentService.deleteStudent();
  9. studentService.updateStudent();
  10. }
  11. }
  1. 前置通知:addStudent
  2. addStudent
  3. 前置通知:deleteStudent
  4. deleteStudent
  5. 前置通知:updateStudent
  6. updateStudent

6、基于XML文件的配置(后置通知)

(1)定义接口和接口的实现类:

  1. public interface StudentService {
  2. void addStudent();
  3. void updateStudent();
  4. String deleteStudent();
  5. }
  1. public class StudentServiceImpl implements StudentService {
  2. @Override
  3. public void addStudent() {
  4. System.out.println("addStudent");
  5. }
  6.  
  7. @Override
  8. public void updateStudent() {
  9. System.out.println("updateStudent");
  10. }
  11.  
  12. @Override
  13. public String deleteStudent() {
  14. System.out.println("deleteStudent");
  15. return "nihao";
  16. }
  17. }

(2)切面类:

  1. public class MyAspect {
  2. public void before(JoinPoint joinPoint){
  3. System.out.println("前置通知:"+ joinPoint.getSignature().getName());
  4. }
  5.  
  6. public void after(JoinPoint joinPoint,Object ret){//参数一:连接点描述
  7. //参数二:类型Object,参数名returning配置的
  8. System.out.println("后置通知:"+ joinPoint.getSignature().getName()+" "+ret);
  9. }
  10. }

(3)配置文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns="http://www.springframework.org/schema/beans"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/aop
  8. http://www.springframework.org/schema/aop/spring-aop.xsd">
  9. <!--目标类-->
  10. <bean id="studentService" class="pers.zhb.aspectxml.StudentServiceImpl"></bean>
  11. <!--切面类-->
  12. <bean id="myAspect" class="pers.zhb.aspectxml.MyAspect"></bean>
  13. <!--aop编程
  14. 将切面类声明为切面,从而获得通知(方法)
  15. ref:切面类引用
  16. -->
  17. <aop:config>
  18. <aop:aspect ref="myAspect">
  19. <!--引入切面类,从中获得通知(方法)
  20. expression:切入点表达式
  21. id:名称,用于其他通知引用
  22. -->
  23. <aop:pointcut id="myPointCut" expression="execution(* pers.zhb.aspectxml.StudentServiceImpl.*(..))"></aop:pointcut>
  24. <!--
  25. method:通知,即方法名
  26. pointcut:切入点表达式,此表达式只能当前通知使用
  27. pointcut-ref:切入点的引用,可以和其它通知共享切入点
  28. returning:通知方法第二个参数的名称
  29. -->
  30. <aop:before method="before" pointcut-ref="myPointCut"></aop:before>
  31. <aop:after-returning method="after" pointcut-ref="myPointCut" returning="ret"></aop:after-returning>
  32.  
  33. </aop:aspect>
  34. </aop:config>
  35. </beans>

(4)测试类:

  1. public class TestAspectXml {
  2. public static void main(String[] args) {
  3. ApplicationContext applicationContext=new
  4. ClassPathXmlApplicationContext("applicationContext.xml");
  5. //获得目标类
  6. pers.zhb.aspectxml.StudentService studentService= (StudentService) applicationContext.getBean("studentService");
  7. studentService.addStudent();
  8. studentService.deleteStudent();
  9. studentService.updateStudent();
  10. }
  11. }
  1. 前置通知:addStudent
  2. addStudent
  3. 后置通知:addStudent null
  4. 前置通知:deleteStudent
  5. deleteStudent
  6. 后置通知:deleteStudent nihao
  7. 前置通知:updateStudent
  8. updateStudent
  9. 后置通知:updateStudent null

7、基于XML文件的配置(环绕通知)

(1)切面类:

  1. public class MyAspect {
  2. public void before(JoinPoint joinPoint){
  3. System.out.println("前置通知:"+ joinPoint.getSignature().getName());
  4. }
  5.  
  6. public void after(JoinPoint joinPoint,Object ret){//参数一:连接点描述
  7. //参数二:类型Object,参数名returning配置的
  8. System.out.println("后置通知:"+ joinPoint.getSignature().getName()+" "+ret);
  9. }
  10. public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
  11. //手动执行目标方法
  12. System.out.println("前");
  13. Object object=proceedingJoinPoint.proceed();
  14. System.out.println("后");
  15. return null;
  16. }
  17. }

(2)配置文件:

  1. <aop:around method="around" pointcut-ref="myPointCut"></aop:around>

(3)测试结果:

  1. 前置通知:addStudent

  2. addStudent

  3. 后置通知:addStudent null
  4. 前置通知:deleteStudent

  5. deleteStudent

  6. 后置通知:deleteStudent null
  7. 前置通知:updateStudent

  8. updateStudent

  9. 后置通知:updateStudent null

8、基于XML文件的配置(抛出异常)

(1)定义目标类的接口和接口的实现类:

  1. public interface StudentService {
  2. void addStudent();
  3. void updateStudent();
  4. String deleteStudent();
  5. }

在方法中制造异常:

  1. public class StudentServiceImpl implements StudentService {
  2. @Override
  3. public void addStudent() {
  4. System.out.println("addStudent");
  5. }
  6.  
  7. @Override
  8. public void updateStudent() {
  9. int num=9/0;
  10. System.out.println("updateStudent");
  11. }
  12.  
  13. @Override
  14. public String deleteStudent() {
  15. System.out.println("deleteStudent");
  16. return "nihao";
  17. }
  18. }

(2)切面类:

  1. public class MyAspect {
  2. public void before(JoinPoint joinPoint){
  3. System.out.println("前置通知:"+ joinPoint.getSignature().getName());
  4. }
  5.  
  6. public void after(JoinPoint joinPoint,Object ret){//参数一:连接点描述
  7. //参数二:类型Object,参数名returning配置的
  8. System.out.println("后置通知:"+ joinPoint.getSignature().getName()+" "+ret);
  9. }
  10. public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
  11. //手动执行目标方法
  12. System.out.println("前");
  13. Object object=proceedingJoinPoint.proceed();
  14. System.out.println("后");
  15. return null;
  16. }
  17. public void AfterThrowing(JoinPoint joinPoint,Throwable throwable){
  18. System.out.println("抛出异常的通知:"+throwable.getMessage());
  19. }
  20. }

(3)配置文件:

  1. <aop:after-throwing method="AfterThrowing" pointcut-ref="myPointCut" throwing="throwable"></aop:after-throwing>

(4)测试:

  1. 前置通知:addStudent

  2. addStudent

  3. 后置通知:addStudent null
  4. 前置通知:deleteStudent

  5. deleteStudent

  6. 后置通知:deleteStudent null
  7. 前置通知:updateStudent

  8. 抛出异常的通知:/ by zero
  9. Exception in thread "main" java.lang.ArithmeticException: / by zero

9、基于XML文件的配置(最终通知)

(1)目标类的接口和接口的实现类:

  1. public interface StudentService {
  2. void addStudent();
  3. void updateStudent();
  4. String deleteStudent();
  5. }
  1. public class StudentServiceImpl implements StudentService {
  2. @Override
  3. public void addStudent() {
  4. System.out.println("addStudent");
  5. }
  6.  
  7. @Override
  8. public void updateStudent() {
  9. int num=9/0;
  10. System.out.println("updateStudent");
  11. }
  12.  
  13. @Override
  14. public String deleteStudent() {
  15. System.out.println("deleteStudent");
  16. return "nihao";
  17. }
  18. }

(2)切面类:

  1. public class MyAspect {
  2. public void before(JoinPoint joinPoint){
  3. System.out.println("前置通知:"+ joinPoint.getSignature().getName());
  4. }
  5.  
  6. public void after(JoinPoint joinPoint,Object ret){//参数一:连接点描述
  7. //参数二:类型Object,参数名returning配置的
  8. System.out.println("后置通知:"+ joinPoint.getSignature().getName()+" "+ret);
  9. }
  10. public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
  11. //手动执行目标方法
  12. System.out.println("前");
  13. Object object=proceedingJoinPoint.proceed();
  14. System.out.println("后");
  15. return null;
  16. }
  17. public void AfterThrowing(JoinPoint joinPoint,Throwable throwable){
  18. System.out.println("抛出异常的通知:"+throwable.getMessage());
  19. }
  20.  
  21. public void myafter(JoinPoint joinPoint){
  22. System.out.println("最终通知");
  23. }
  24. }

(3)配置文件:

  1. <aop:after method="myafter" pointcut-ref="myPointCut"></aop:after>

(4)测试结果:

  1. 前置通知:addStudent

  2. addStudent
  3. 最终通知


  4. 后置通知:addStudent null
  5. 前置通知:deleteStudent

  6. deleteStudent
  7. 最终通知


  8. 后置通知:deleteStudent null
  9. 前置通知:updateStudent

  10. 最终通知
  11. 抛出异常的通知:/ by zero
  12. Exception in thread "main" java.lang.ArithmeticException: / by zero

不管有没有异常都会执行最终通知。

10、基于注解的配置

(1)目标类的接口和接口的实现类:

  1. public interface StudentService {
  2. void addStudent();
  3. void updateStudent();
  4. String deleteStudent();
  5. }
  1. import org.springframework.stereotype.Service;
  2. @Service("studentService")
  3. public class StudentServiceImpl implements StudentService {
  4. @Override
  5. public void addStudent() {
  6. System.out.println("addStudent");
  7. }
  8.  
  9. @Override
  10. public void updateStudent() {
  11. int num=9/0;
  12. System.out.println("updateStudent");
  13. }
  14.  
  15. @Override
  16. public String deleteStudent() {
  17. System.out.println("deleteStudent");
  18. return "nihao";
  19. }
  20. }

(2)配置文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns="http://www.springframework.org/schema/beans"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/aop
  9. http://www.springframework.org/schema/aop/spring-aop.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context.xsd">
  12. <!--扫描注解-->
  13. <context:component-scan base-package="pers.zhb.aspectxml"></context:component-scan>
  14. <!--确定aop注解生效-->
  15. <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  16. </beans>

(3)切面:

  1. @Component
  2. @Aspect//声明切面
  3. public class MyAspect {
  4. @Before("execution(* pers.zhb.aspectxml.StudentServiceImpl.*(..))")
  5. public void before(JoinPoint joinPoint){
  6. System.out.println("前置通知:"+ joinPoint.getSignature().getName());
  7. }
  8.  
  9. //声明公共切入点
  10. @Pointcut("execution(* pers.zhb.aspectxml.StudentServiceImpl.*(..))")
  11. private void myPointCut(){
  12.  
  13. }
  14. @AfterReturning(value = "myPointCut()",returning = "ret")
  15. public void after(JoinPoint joinPoint,Object ret){//参数一:连接点描述
  16. //参数二:类型Object,参数名returning配置的
  17. System.out.println("后置通知:"+ joinPoint.getSignature().getName()+" "+ret);
  18. }
  19.  
  20. @Around(value = "myPointCut()")
  21. public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
  22. //手动执行目标方法
  23. System.out.println("前");
  24. Object object=proceedingJoinPoint.proceed();
  25. System.out.println("后");
  26. return null;
  27. }
  28.  
  29. @AfterThrowing(value = "execution(* pers.zhb.aspectxml.StudentServiceImpl.*(..))",throwing = "throwable")
  30. public void AfterThrowing(JoinPoint joinPoint,Throwable throwable){
  31. System.out.println("抛出异常的通知:"+throwable.getMessage());
  32. }
  33.  
  34. @After(value = "myPointCut()")
  35. public void myafter(JoinPoint joinPoint){
  36. System.out.println("最终通知");
  37. }
  38. }

(4)测试:

  1. public class TestAspectXml {
  2. public static void main(String[] args) {
  3. ApplicationContext applicationContext=new
  4. ClassPathXmlApplicationContext("applicationContext.xml");
  5. //获得目标类
  6. pers.zhb.aspectxml.StudentService studentService= (StudentService) applicationContext.getBean("studentService");
  7. studentService.addStudent();
  8. studentService.deleteStudent();
  9. studentService.updateStudent();
  10. }
  11. }

  1. 前置通知:addStudent
  2. addStudent

  3. 最终通知
  4. 后置通知:addStudent null

  5. 前置通知:deleteStudent
  6. deleteStudent

  7. 最终通知
  8. 后置通知:deleteStudent null

  9. 前置通知:updateStudent
  10. 最终通知
  11. 抛出异常的通知:/ by zero
  12. Exception in thread "main" java.lang.ArithmeticException: / by zero

spring的AspectJ基于XML和注解(前置、后置、环绕、抛出异常、最终通知)的更多相关文章

  1. Spring -- aop(面向切面编程),前置&后置&环绕&抛异常通知,引入通知,自动代理

    1.概要 aop:面向方面编程.不改变源代码,还为类增加新的功能.(代理) 切面:实现的交叉功能. 通知:切面的实际实现(通知要做什么,怎么做). 连接点:应用程序执行过程期间,可以插入切面的地点. ...

  2. spring之AspectJ基于xml AOP编程

    一.引言: AspectJ框架不仅实现了面向切面编程,而且还支持注解,spring将它引入自己的规范之中. 二.需要了解: AspectJ是基于java语言的AOP框架 spring2.0之后支持As ...

  3. MyBatis 项目开发中是基于 XML 还是注解?

    只要你对 MyBatis 有所认识和了解,想必知道 MyBatis 有两种 SQL 语句映射模式,一种是基于注解,一种是基于XML. 基于 XML <mapper namespace=" ...

  4. spring 切面 前置后置通知 环绕通知demo

    环绕通知: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:// ...

  5. Spring Bean前置后置处理器的使用

    Spirng中BeanPostProcessor和InstantiationAwareBeanPostProcessorAdapter两个接口都可以实现对bean前置后置处理的效果,那这次先讲解一下B ...

  6. AOP 环绕通知 集成了前置 后置 返回通知等功能

    AOP 环绕通知 集成了前置 后置 返回通知等功能

  7. pytest_前置后置

    今天总结下pytest,pytest简直就是python自动化中的高富帅,各种操作,哈哈 这次总结主要涉及到了以下几点: 1.unittest中的setUp.tearDown.setUpClass.t ...

  8. unittest的前置后置,pytest的fixture和共享机制conftest.py

    Unittest setUp/tearDown setUp当中得到的变量,用self.xxx = value传递给测试用例 setUpClass/tearDownClass setupClass当中得 ...

  9. spring之AspectJ基于注解 AOP编程

    一.前言 使用注解代替之前在spring配置文件中配置目标类.切面类和aop配置. 二.注意 需要注意的是,需要在spring配置文件中引入如下,如果不添加,切面类中的@Aspect注解将不起作用 & ...

随机推荐

  1. Learning in Spiking Neural Networks by Reinforcement of Stochastic Synaptic Transmission

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Summary 众所周知,化学突触传递是不可靠的过程,但是这种不可靠的函数仍然不清楚.在这里,我考虑这样一个假设,即大脑利用突触传递的随机 ...

  2. MySQL优化--IO调度算法优化

    之前已经在微信公众号分享了数据库优化的方法,链接为https://mp.weixin.qq.com/s/6Atzk9UKPJRxxAs0nsKBXg . 其中操作系统部分介绍了IO调度算法的优化,本文 ...

  3. Netty之旅二:口口相传的高性能Netty到底是什么?

    高清思维导图原件(xmind/pdf/jpg)可以关注公众号:一枝花算不算浪漫 回复netty01即可. 前言 上一篇文章讲了NIO相关的知识点,相比于传统IO,NIO已经做得很优雅了,为什么我们还要 ...

  4. shell 三剑客之 sed

    sed 在shell 编程里也很常用,功能强大! 同grep一样,sed提供两种方式: 方式一:stdout | sed [option] "pattern command" 从文 ...

  5. 速记OSI七层协议模型

    OSI七层协议模型 第一层:物理层(Physical) 第二层:数据链路层(Data-Link) 第三层:网络层(NetWork) 第四层:传输层(Transport) 第五层:会话层(Session ...

  6. Java抽象类简述

    Java 抽象类 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类除了不 ...

  7. App 自动化,Appium 凭什么使用 UiAutomator2?

    1. UiAutomator2 是什么 可能很多人对 UiAutomator2 和 UiAutomator 傻傻分不清楚 UiAutomator 是 Google 开发的一款运行在 Android 设 ...

  8. 阿里大牛教你基于Python的 Selenium自动化测试示例解析

    今天给大家讲解的是自动化测试示例的解析,如有不对的地方请多多指教. 自动化测试示例如下: from selenium import webdriver from selenium.webdriver. ...

  9. 【Android】安卓开发之activity如何传值到fragment,activity与fragment传值

    作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 大家知道,我们利用activity使 ...

  10. 【Android】Android开发初学者实现拨打电话的功能,拨打电话app小demo实现

    作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 首先先给大家看一下最终实现的效果: ...