系列文章目录

实习笔记 —— Spring基础
实习笔记 —— IOC反转控制(xml配置文件 + 注解)
实习笔记 —— AOP开发I


文章目录

  • 系列文章目录
  • 一、AOP中Advice的类型的XML配置文件形式
  • 二、AOP中Advice的类型的基本注解形式
  • 三、AOP中Advice的类型的切入点注解形式
  • 四、总结

一、AOP中Advice的类型的XML配置文件形式

先回顾昨天学的AOP中的相关术语,体会Advice的含义:

实习时介绍了AOP中Advice的五种类型,我们将这五种类型综合起来学习。

1.before advice前置通知: 在执行切点前的通知,可以判断是否可以执行该切点。

2.after-returning advice后置通知: 在运行完切点完未返回之前,进行通知。

3.around advice环绕通知: 包裹一个方法的执行,这是一个功能强大的通知方式。可以在方法执行前或者执行后around advice,也可以用来判断是否往下执行当前的切点,或者返回切点的值。或者抛出一个异常。

4.after throwing advice异常通知: 在运行完切点时抛出异常进行的通知。

5.After advice最终通知:执行完该切点后,进行的通知。

以具体项目为例:(创建项目第一步先导包)

①声明接口:

②声明接口的实现类:

③创建切面类,将所有新添加的需求对应的方法写在这里:

package com.high.demo1;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;//最开始导错包了import org.aopalliance.intercept.Joinpoint;// 切面类,存放用户要增加的方法
public class MyAspectXML {// Advice:通知,增强;甲方要求新增加的方法或需求(如显示用户身份需求)
//  public void checkPri() {//      System.out.println("进行身份验证........");
//  } // ctrl + alt + down// 1.前置通知public void checkPri(JoinPoint jointJoinpoint) {System.out.println("save方法的前置通知:进行身份验证........" + jointJoinpoint);}// 2.后置通知public void writeLog(Object result) {System.out.println("delete方法的后置通知:Be recorded....." + result);}// 3.环绕通知:性能监控// ProceedingJoinPoint是指被增加的接入点find()public Object aroundOne(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("环绕通知前.....");// 调用了此方法对应的切入点 find()方法,基本都要写,用于体现“环绕”Object proceed = joinPoint.proceed();       System.out.println("环绕通知后前.....");return proceed;}// 4.异常抛出通知// 参数: Throwablepublic void afterThrow(Throwable ex) {System.out.println("Error appeared." + ex.getMessage());}// 5.最终通知 —— 相当于异常中的 finally代码块public void afterLast() {System.out.println("This is the final Advice.");}
}

④编写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: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"><!-- 把ProductDaoImpl类交给spring管理 --><!-- 创建目标类 target --><bean name="productDao" class="com.high.demo1.ProductDaoImpl"></bean>      <!-- 将切面类交给spring管理 --><bean name="myAspect" class="com.high.demo1.MyAspectXML"></bean>  <!-- 通过AOP配置来完成对目标的代理 --><!-- MyAspectXML类中的checkPri作用于切入点pointcut1上 --><aop:config><!-- 声明第一个切入点,id值全局唯一 --> <aop:pointcut id="pointcut1" expression="execution(* com.high.demo1.ProductDaoImpl.save(..))"/><aop:pointcut id="pointcut2" expression="execution(* com.high.demo1.ProductDaoImpl.delete(..))"/><aop:pointcut id="pointcut3" expression="execution(* com.high.demo1.ProductDaoImpl.find(..))"/><aop:pointcut id="pointcut4" expression="execution(* com.high.demo1.ProductDaoImpl.update(..))"/><aop:pointcut id="pointcut5" expression="execution(* com.high.demo1.ProductDaoImpl.find(..))"/><!-- 引入切面类MyAspect  --><aop:aspect ref="myAspect"><!-- 完成织入过程,切面类作用在谁身上(只写方法名),以及切入点 --><!-- 通知的类型:1.前置通知 before --><aop:before method="checkPri" pointcut-ref="pointcut1"/><!-- 2.后置通知 after-returning --><aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/><!-- 3.环绕通知 --><aop:around method="aroundOne" pointcut-ref="pointcut3"/><!-- 4.异常通知 --><aop:after-throwing method="afterThrow" pointcut-ref="pointcut4" throwing="ex"/><!-- 5.最终通知 --><aop:after method="afterLast" pointcut-ref="pointcut5"/></aop:aspect></aop:config>
</beans>

⑤编写测试类:

package com.high.demo1;import javax.annotation.Resource;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;// AOP入门
// 书写类注解,类层级,所以写在类外面
// 整合JUnit4
@RunWith(SpringJUnit4ClassRunner.class)
// 加载XML配置文件(严格按照格式书写,不要添加任何空格等字符)
@ContextConfiguration("classpath:applicationContext.xml")public class SpringDemo {// 1.未使用注解整合JUnit
//  @Test
//  public void demo() {//      ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//      ProductDaoImpl product = (ProductDaoImpl)applicationContext.getBean("productDao");
//
//      product.save();
//      product.update();
//      product.delete();
//      product.find();
//  }// 2.整合后// 想用哪个类就注入哪个类,交给spring管理// 对私有属性的引入@Resource(name = "productDao")private ProductDao productDao;@Testpublic void demo2() {productDao.save();productDao.update();productDao.delete();productDao.find();}
}

在正常无Advice的情况下,测试类的输出结果为:

在为各个方法添加新需求后:体会五种类型的Advice的作用

二、AOP中Advice的类型的基本注解形式

核心:
在配置文件中启用注解功能:

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

①创建类(应该是接口及其实现类,偷懒了):

②编写配置文件:
由于使用注解形式弱化了配置文件的作用,所以配置文件精简了许多

③最核心的部分:编写切面类

package com.high.demo;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;// 切面类
// AOP注解
@Aspect
public class MyAspectDemo {// 1.前置增强@Before(value = "execution(* com.high.demo.OrderDao.save(..))")public void checkPri(JoinPoint joinPoint) {System.out.println("save方法的前值增强:权限检测..." + joinPoint);}// 2.后置增强@AfterReturning(value = "execution(* com.high.demo.OrderDao.find(..))", returning = "result")public void afterReturn(String result) {System.out.println("find方法的后置增强..." + result);}// 3.环绕增强@Around(value = "execution(* com.high.demo.OrderDao.delete(..))")public Object aroundOne(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("delete方法的环绕前通知");// 获取接入点Object target = joinPoint.proceed();System.out.println("delete方法的环绕后通知");return target;}// 4.异常通知@AfterThrowing(value = "execution(* com.high.demo.OrderDao.update(..))", throwing="ex")public void afterThrowing(Throwable ex) {System.out.println("update方法的异常通知:Error appeared: " + ex.getMessage());}// 5.最终通知@After(value = "execution(* com.high.demo.OrderDao.update(..))")public void afterAdvice() {System.out.println("This is the After Advice of method update.");}
}

④测试类:
测试类完全使用注解形式了,比之前的先获取配置文件再使用对象及其方法的形式简便了一些

测试结果:

当解除 update 方法的注释 i = 1 / 0 后,代码中出现 0 作分母的错误,此时异常通知就开始起作用了(update 方法未能成功执行,而针对update 方法的最终通知无论如何都会执行)

三、AOP中Advice的类型的切入点注解形式

这是最简便的书写方式了,相对于标题二中的基本注解形式,进一步简化代码,声明切入点的注解,使得不必再对方法的每个新增需求创建切入点,而是对每个原有方法声明切入点,大大减少了需要声明的切入点的个数。

在切面类中写@Aspect注解,并在类中用注解进行切入点的声明(这是注解方式相较于XML配置文件方式简练的点,不再需要在XML配置文件中单独声明切入点并编写织入过程了)

其实实体类、测试类、配置文件相对于标题二下的内容都没有修改,只是在切面类中增加了切入点的注解:

①加入切入点注解的切面类写法:

package com.high.demo2;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;@Aspect // 最开始给忘喽
public class MyAspect {// AOP切入点的注解,提供更大的灵活性,方便解耦@Pointcut(value = "execution(* com.high.demo2.UserDao.save(..))")private void pointcut1() {}; //此处是一个方法,不是变量@Pointcut(value = "execution(* com.high.demo2.UserDao.find(..))")private void pointcut2() {};@Pointcut(value = "execution(* com.high.demo2.UserDao.delete(..))")private void pointcut3() {};@Pointcut(value = "execution(* com.high.demo2.UserDao.update(..))")private void pointcut4() {};// 1.前置通知@Before(value = "MyAspect.pointcut1()")public void checkPri(JoinPoint joinPoint) {System.out.println("切入点注解测试:save方法的前置通知; " + joinPoint);}// 2.后置通知@AfterReturning(value = "MyAspect.pointcut2()", returning = "result")public void afterOne(String result) {System.out.println("切入点注解测试:find方法的后置通知; " + result);}// 3.环绕通知@Around(value = "MyAspect.pointcut3()")public Object aroundOne(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("切入点注解测试:delete方法的环绕通知(前);");// 获取接入点Object target = joinPoint.proceed();System.out.println("切入点注解测试:delete方法的环绕通知(后);");return target;}// 4.异常通知@AfterThrowing(value = "MyAspect.pointcut4()", throwing = "ex")public void afterThrowing(Throwable ex) {System.out.println("切入点注解测试:update方法的异常通知; " + ex.getMessage());}// 5.最终通知@After(value = "MyAspect.pointcut4()")public void afterAdvice() {System.out.println("切入点注解测试:update方法的最终通知;");}
}

②测试结果:
(尽管实体类等没有变化,但在切面类书写 Advice 时在熟练之后对各输出语句内容进行了自由发挥,整体代码自认为更容易理解了。)

四、总结

1.后置通知在return语句前输出。

2.异常通知是报错时才会出现的通知,after-throwing 中的after 是指在执行后才能发现异常。
(同时发现:在项目spring03中测试时,按照测试类调用方法的顺序,update执行错误后剩余的delete和find不执行了。)

3.关于最终通知,若异常测试对应的方法(切入点)出错,最终通知会显示在异常测试报错之前,再报错。

4.若所有的新增需求甲方都不要了,我们要改哪些代码?
——在配置文件中将切面类相关的代码删除,保留

<bean name="productDao" class="com.high.demo1.ProductDaoImpl"></bean>

仍可在测试类中以XML配置文件形式使用spring框架对对象进行操作。

5.声明切入点时的expression属性写法(spring的切入点表达式写法):

6.注解有两种:类层面的注解 + 方法/属性层面(类内部)的注解。

7.spring注重团队开发与规则,便于大规模使用。类比自家饭菜与连锁店,自家饭菜一家一个味,但不利于形成规模。

8.代码能力相对容易掌握,但排错能力需要经验与锻炼。日常的节奏是写一段代码,报错,排错,完善,再往下写。

实习笔记—— AOP开发II(AOP中Advice的类型)相关推荐

  1. 实习笔记 —— springMVC部分II

    系列文章目录 实习笔记 -- Spring基础 实习笔记 -- IOC反转控制(xml配置文件 + 注解) 实习笔记 -- AOP开发I 实习笔记 -- AOP开发II(AOP中Advice的类型) ...

  2. iOS开发笔记之九十四——Swift中的可选类型Optional

    一.Optional类型的概念 Swift中为何要引入Optional的概念,官方文档中有介绍: Swift also introduces optional types, which handle ...

  3. JavaEE——Spring学习笔记03【AOP开发】

    JavaEE--Spring学习笔记01[Ioc开发的模式] JavaEE--Spring学习笔记02[Spring和Mybatis的整合] JavaEE--Spring学习笔记03[AOP开发] J ...

  4. 实习笔记 —— Git II(远程提交)

    系列文章目录 实习笔记 -- Spring基础 实习笔记 -- IOC反转控制(xml配置文件 + 注解) 实习笔记 -- AOP开发I 实习笔记 -- AOP开发II(AOP中Advice的类型) ...

  5. 实习笔记 —— MyBatis II (MyBatis基本数据库操作)

    系列文章目录 实习笔记 -- Spring基础 实习笔记 -- IOC反转控制(xml配置文件 + 注解) 实习笔记 -- AOP开发I 实习笔记-- AOP开发II(AOP中Advice的类型) 实 ...

  6. 实习笔记 —— MyBatis III (输入/输出映射)

    系列文章目录 实习笔记 -- Spring基础 实习笔记 -- IOC反转控制(xml配置文件 + 注解) 实习笔记 -- AOP开发I 实习笔记-- AOP开发II(AOP中Advice的类型) 实 ...

  7. 实习笔记 —— SSM三个框架的整合 V (分页功能)

    系列文章目录 实习笔记 -- Spring基础 实习笔记 -- IOC反转控制(xml配置文件 + 注解) 实习笔记 -- AOP开发I 实习笔记 -- AOP开发II(AOP中Advice的类型) ...

  8. 实习笔记 —— Maven

    系列文章目录 实习笔记 -- Spring基础 实习笔记 -- IOC反转控制(xml配置文件 + 注解) 实习笔记 -- AOP开发I 实习笔记 -- AOP开发II(AOP中Advice的类型) ...

  9. 实习笔记 —— SSM三个框架的整合 III (对后台管理页面进行编写)

    系列文章目录 实习笔记 -- Spring基础 实习笔记 -- IOC反转控制(xml配置文件 + 注解) 实习笔记 -- AOP开发I 实习笔记 -- AOP开发II(AOP中Advice的类型) ...

最新文章

  1. 算法-链表-给定一个数小于该值的在左边等于在中间大于的在右边
  2. python3 random函数_Python3 中 random模块
  3. 【数据挖掘】基于密度的聚类方法 - OPTICS 方法 ( 核心距离 | 可达距离 | 族序 )
  4. bpython使用_使用Python实现一个简单的A/B测试
  5. Java基础--访问权限控制符
  6. 作为一名程序员,我站在人生的十字路口
  7. 6_机器翻译与Seq2Seq模型
  8. 【MyBatis源码解析】MyBatis一二级缓存
  9. 熊猫merge()–合并两个DataFrame对象
  10. php中的数据库操作类、分页类,以及smarty扩展类
  11. jQuery实现textarea高度根据内容自适应
  12. 如何制做计算机病毒,电脑病毒制作-怎么制作电脑病毒请教高手,怎么做病毒? – 手机爱问...
  13. 打开组策略 计算机配置,组策略命令,小编告诉你电脑组策略怎么打开
  14. OKR工作法学习心得
  15. 以计算机为主题的想象作文,以想象为话题的作文(通用13篇)
  16. 解决使用CSV包,将写入字符串写入csv文件时字符串被拆分成很多单元的问题
  17. FPGA原理和结构简介
  18. 方案设计阶段目标成本形成过程
  19. Python sqlalchemy 连接常用的数据库
  20. Java 应该怎么学

热门文章

  1. ibatis中配置parameterClass=java.util.HashMap的用法
  2. 播放失败246106异常代码_三菱-菱云系列电梯故障代码
  3. 李航:做本质的、严谨的、有意思的研究!
  4. APACHE官网下载历史版本TOMCAT(以8.5.6版本为例)
  5. 清理Ubuntu虚拟机磁盘空间
  6. sublime插件 —— 一键美化HTML/CSS/JS代码
  7. 东网科技、Rancher Labs联合发布“容器+虚拟化”双引擎超融合平台HOR
  8. JAVA在线观看视频教程完整版
  9. seq2seq(序列到序列)模型
  10. Life Long Learning论文初探————Online Fast Adaptation and Knowledge Accumulation(OSAKA)