一、AspectJ

1、介绍

  AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,也可以说 AspectJ 是一个基于 Java 语言的 AOP 框架。通常我们在使用 Spring AOP 的时候,都会导入 AspectJ 的相关 jar 包。

2、案例(xml)

  定义目标对象(被代理的对象)(与上一章相同)
  编写一个切面类(通知)

 1 // 创建切面类(包含各种通知)
2 public class MyAspect {
3
4 // JoinPoint 能获取目标方法的一些基本信息
5 public void myBefore(JoinPoint joinPoint) {
6 System.out.println("前置通知:方法增强myBefore()" + " , -->" + joinPoint.getSignature().getName());
7 }
8
9 // object:目标方法的返回值
10 public void myAfterReturning(JoinPoint joinPoint, Object object) {
11 System.out.println("后置通知:方法增强myAfterReturning()" + " , -->" + joinPoint.getSignature().getName() + " , -->" + object);
12 }
13
14 public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable {
15 System.out.println("============环绕前==============");
16 Object obj = joinPoint.proceed(); // 手动执行目标方法
17 System.out.println("============环绕后==============");
18 return obj;
19 }
20
21 public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
22 System.out.println("抛出异常通知:" + e.getMessage());
23 }
24
25 public void myAfter() {
26 System.out.println("最终通知:方法增强myAfter()");
27 }
28
29 }

  编写配置文件 application.xml

 1 <!-- 配置目标对象 -->
2 <bean id="teacher" class="com.lx.spring.common.Teacher"/>
3 <!-- 配置切面对象(通知) -->
4 <bean id="myAspect" class="com.lx.spring.day3.MyAspect"/>
5
6 <aop:config>
7 <!-- 切入点表达式,指明了在哪里引入通知 -->
8 <aop:pointcut id="myPointcut" expression="execution(* com.lx.spring.common.ITeacher.*(..))"/>
9
10 <!-- 方法增强,指明了引入一个什么样的通知 -->
11 <aop:aspect ref="myAspect">
12 <aop:before method="myBefore" pointcut-ref="myPointcut"/>
13 <aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut" returning="object"/>
14 <aop:around method="myAround" pointcut-ref="myPointcut"/>
15 <aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointcut" throwing="e"/>
16 <aop:after method="myAfter" pointcut-ref="myPointcut"/>
17 </aop:aspect>
18 </aop:config>
 1 // 测试类
2 public class Main {
3 public static void main(String[] args) {
4 ApplicationContext app = new ClassPathXmlApplicationContext("app3.xml");
5 ITeacher iTeacher = app.getBean(ITeacher.class);
6
7 iTeacher.add(11, 24);
8 }
9 }
10
11 // 结果一:未配置环绕通知时.注意:此时 最终通知 在 后置通知后面
12 前置通知:方法增强myBefore() , -->add
13 执行目标方法:老师正在做加法,结果为:35
14 后置通知:方法增强myAfterReturning() , -->add , -->35
15 最终通知:方法增强myAfter()
16
17
18 // 结果二:配置环绕通知时.注意:此时 最终通知 在 后置通知前面
19 前置通知:方法增强myBefore() , -->add
20 ============环绕前==============
21 执行目标方法:老师正在做加法,结果为:35
22 最终通知:方法增强myAfter()
23 ============环绕后==============
24 后置通知:方法增强myAfterReturning() , -->add , -->35

  说明:这里有很多细节需要补充一下。深刻理解通知,重点思想在于:①在哪里(切点,或者说方法)引入?②引入一个什么样的通知?针对这两个问题,则不难理解AOP。
  ①切入点表达式:指明了在哪里(切点,在哪个方法)引入一个通知(即对目标方法的增强),也就是在哪些方法进行增强。execution 是 AspectJ 框架定义的一个切入点函数,其语法形式如下:

1 execution(modifiers-pattern? ref-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
2 类修饰符 返回值 方法所在的包 方法名(参数) 方法抛出的异常

  那么不难理解,对满足以下规则的方法进行增强。也就是对这些方法引入一个通知。

1 <aop:pointcut id="myPointcut" expression="execution(* com.lx.spring.common.ITeacher.*(..))"/>
2 选择方法 任意返回值 此包下.此接口 任意方法名(任意参数)

  ②通知(方法增强):指明了对满足切点表达式的方法引入一个什么样的通知。

 1 <!-- 指明引入的切面(通知) -->
2 <aop:aspect ref="myAspect">
3 <!-- 对满足上面切入点表达式的方法配置一个前置通知 -->
4 <!-- 即在目标方法前执行方法 myBefore -->
5 <aop:before method="myBefore" pointcut-ref="myPointcut"/>
6
7 <!-- 对满足上面切入点表达式的方法配置一个后置通知 -->
8 <!-- 即在目标方法后执行方法 myAfterReturning -->
9 <aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut" returning="object"/>
10 </aop:aspect>

3、切入点表达式

  上一节中已经介绍过切入点表达式的相关语法,且理解不难。再补充几点,如果切入点表达式有多个不同目录呢?可以通过 || 来表示或的关系。

1 <!--表示匹配com.lx.aop包下的,以Service结尾或者以Facade结尾的类的任意方法。-->
2 <aop:pointcut id="myPointcut" expression="execution(* com.lx.aop.*Service.*(..)) || execution(* com.lx.aop.*Facade.*(..))"/>

  AOP 切入点表达式支持多种形式的定义规则:

 1 1、execution:匹配方法的执行(常用)
2 execution(public *.*(..))
3 2、within:匹配包或子包中的方法(了解)
4 within(com.ys.aop..*)
5 3、this:匹配实现接口的代理对象中的方法(了解)
6 this(com.ys.aop.user.UserDAO)
7 4、target:匹配实现接口的目标对象中的方法(了解)
8 target(com.ys.aop.user.UserDAO)
9 5、args:匹配参数格式符合标准的方法(了解)
10 args(int,int)
11 6、bean(id):对指定的bean所有的方法(了解)
12 bean('userServiceId')

4、通知类型

通知类型
接口
描述
前置通知
(before)
org.springframework.aop.aspectj.AspectJMethodBeforeAdvice
在目标方法前调用,如果通过抛出异常,阻止方法运行。
应用:各种校验。
后置通知
(afterReturning)
org.springframework.aop.aspectj.AspectJAfterReturningAdvice
在目标方法后调用,可以获得目标方法返回值,若目标方法抛出异常,通知无法执行。
应用:常规数据处理。
环绕通知
(around)
org.springframework.aop.aspectj.AspectJAroundAdvice
在目标方法前后调用,可以阻止方法的执行,必须手动执行目标方法。
应用:十分强大,可以做任何事情。
异常通知
(afterThrowing)
org.springframework.aop.aspectj.AspectJAfterThrowingAdvice
目标方法抛出异常时调用,若目标方法没有抛出异常,无法执行。
应用:包装异常信息
最终通知
(after)
org.springframework.aop.aspectj.AspectJAfterAdvice
目标方法执行完毕后执行,无论方法中是否出现异常
应用:清理现场

  这里最重要的是around,环绕通知,它可以代替上面的任意通知。

  在程序中表示的意思如下:

 1 public class Main {
2 public static void main(String[] args) {
3 try {
4 // 前置 before
5 // 手动执行目标方法
6 // 后置 afterReturning
7 } catch (Exception e) {
8 // 抛出异常通知 afterThrowing
9 } finally {
10 // 最终 after
11 }
12 }
13 }

  源码:

5、小结

  使用 <aop:config>进行配置,proxy-target-class="true",声明时使用cglib代理;如果不声明,Spring 会自动选择cglib代理还是JDK动态代理。
  SpringAOP 的具体加载步骤:
  ①当 spring 容器启动的时候,加载 spring 的配置文件。
  ②为配置文件中的所有 bean 创建对象。
  ③spring 容器会解析 aop:config 的配置,解析切入点表达式,用切入点表达式和纳入 spring 容器中的 bean 做匹配,如果匹配成功,则会为该 bean 创建代理对象,代理对象的方法 = 目标方法 + 通知;如果匹配不成功,不会创建代理对象。
  ④在客户端利用 context.getBean() 获取对象时,如果该对象有代理对象,则返回代理对象;如果没有,则返回目标对象
  说明:如果目标类没有实现接口,则 spring 容器会采用 cglib 的方式产生代理对象,如果实现了接口,则会采用 jdk 的方式。

Spring5(六)——AspectJ(xml)的更多相关文章

  1. aspectj xml

    1.接口和类 1.1 ISomeService 接口 public interface ISomeService { public void doSome(); public void dade(); ...

  2. Maven学习小结(六 setting.xml详解[转])

    当Maven运行过程中的各种配置,例如pom.xml,不想绑定到一个固定的project或者要分配给用户时,我们使用settings.xml中的settings元素来确定这些配置.这包含了本地仓库位置 ...

  3. Maven学习 六 pom.xml文件

    java jar包的搜索网址:http://mvnrepository.com/ pom作为项目对象模型.通过xml表示maven项目,使用pom.xml来实现.主要描述了项目:包括配置文件:开发者需 ...

  4. Javaweb学习笔记——(六)——————xml中jaxp两种解析方式和dom4j运用

    1.xml的scheam约束 dtd的语法:<!ElEMENT 元素名称 约束> **schema符合xml的语法,xml语句 **一个xml中可以有多个schema,多个schema使用 ...

  5. Python之路(第十六篇)xml模块、datetime模块

    一.xml模块 xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单, xml比较早,早期许多软件都是用xml,至今很多传统公司如金融行业的很多系统的接口还主要 ...

  6. 设计模式(六) xml方式实现AOP

    1.1. Aop,  aspect object programming  面向切面编程 功能: 让关注点代码与业务代码分离! 关注点, 重复代码就叫做关注点: 切面, 关注点形成的类,就叫切面(类) ...

  7. Spring AOP + AspectJ in XML configuration example

    For those don't like annotation or using JDK 1.4, you can use AspectJ in XML based instead. Review l ...

  8. Spring使用AspectJ开发AOP:基于XML

    基于XML的声明式 基于 XML 的声明式是指通过 Spring 配置文件的方式定义切面.切入点及声明通知,而所有的切面和通知都必须定义在 <aop:config> 元素中. 下面通过案例 ...

  9. spring-AOP动态代理,以及aspectJ的xml配置或注解配置方法,各个拦截器的使用顺序

    package com.itheima.aspect; public class MyAspect { public void check_Permissions(){ System.out.prin ...

  10. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring使用AspectJ开发AOP基于XML和基于Annotation

    AspectJ 是一个基于 Java 语言的 AOP 框架,它扩展了 Java 语言.Spring 2.0 以后,新增了对 AspectJ 方式的支持,新版本的 Spring 框架,建议使用 Aspe ...

随机推荐

  1. vue中rem的转换

    1 function rems(doc: any, win: any): void { 2 let docEl = doc.documentElement, 3 resizeEvt = 'orient ...

  2. JUC学习笔记(五)

    JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html JUC学习笔记(二)https://www.cnblogs.com/lm66/p/1511 ...

  3. jmeter之JDBC类组件

    ~什么是JDBC?:全称名为Java DataBase Connectivity,(java数据库连接),在jmeter中是一种可以远程操作数据库的一类组件. ~jmeter如何操作数据库?:jmet ...

  4. 干了快3年Android了,感觉自己的职业生涯已经快凉了

    背景 首先我是个菜鸡,工资也低的一笔. 刚毕业时候在一家国企上班干 app 开发,干了快两年的时候,跳槽到了一家伪大厂干安全.投了不少简历都没有回音,只有这加伪大厂要我就来了.当时说好了会接触一些底层 ...

  5. Spring Cloud Aliaba - Ribbon

    Ribbon(有关介绍见RestTemplate末尾) Ribbon负载均衡实现策略 Ribbon负载均衡实现策略通过接口IRule进行实现,默认使用ZoneAvoidanceRule规则进行负载均衡 ...

  6. git只提交部分修改的文件(提交指定文件)

    在我们的项目中,经常会在本地编译一些代码,还未写完,测试那边来告诉你要改改某个文件的bug,非常着急,此时改完了,提交的时候,自己还在编译的代码并不想提交,此时,你可以利用git这些指令帮助你! 1/ ...

  7. MySQL5.6忘记root密码

    第一步 修改 /etc/my.conf 文件 添加 skip-grant-tables 到 [mysqld] 下面就可以 这个参数的意思是设置为无需密码验证的登录 登录之后,可以添加用户,可以修改密码 ...

  8. kivy之Label属性及文本标记实操练习

    关于kivy内label功能有二部分内容,一个是label小部件属性,另一个是label文本标记属性,实操练习的效果图如下: . 现将label常用的这二类属性整理如下: 现在我们来进行实操练习,在p ...

  9. SpringMVC/boot-CSRF安全方案

    1. CSRF原理与防御方案概述 一. 原理 增删改的接口参数值都有规律可循,可以被人恶意构造增删改接口 将恶意构造的增删改接口发给对应特定用户,让特定用户点击 特定用户使用自己的认证信息对该接口发起 ...

  10. Java 方法使用

    那么什么是方法呢? Java方法是语句的集合,它们在一起执行一个功能. 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 方法的优点 1. 使程序变得更简 ...