1、概述

  切入点(execution ):可以对指定的方法进行拦截,从而给指定的类生成代理对象。(拦截谁,就是在谁那里切入指定的程序/方法)

格式:

  1. execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

参数解析:

modifiers-pattern?:指定方法的修饰符,支持通配符,该部分可以省略。(public/private/protected
  ret-type-pattern:指定方法的返回值类型,支持通配符,可以使用 * 来匹配所有的返回值类型。
  declaring-type-pattern?:指定方法所属的,支持通配符,该部分可以省略。(要切入的类:class
  name-pattern:指定要匹配的方法名,支持通配符,可以使用"*"通配符来匹配所有方法。(要切入的方法
  param-pattern:指定方法声明中的形参列表,支持两个通配符,即"*"和"..",其中“*”代表一个任意类型的参数,而“..”代表零个或多个任意类型的参数。例如,() 匹配一个不接受任何参数的方法,而(..) 匹配一个接受任意数量参数的方法,(*)匹配了一个接受一个任何类型的参数的方法,(*,String)匹配了一个接受两个参数的方法,其中第一个参数是任意类型,第二个参数必须是String类型。(要切入的方法的参数列表)
  throws-pattern:指定方法声明抛出的异常,支持通配符,该部分可以省略。

切入点语法常用的几种:

  1. <!-- 切入点表达式语法: -->
  2. <!-- 【1、拦截所有public方法】 -->
  3. <aop:pointcut expression="execution(public * *(..))" id="pt"/>
    4
  4. <!-- 【2、拦截所有save开头的方法】 -->
  5. <aop:pointcut expression="execution(* save*(..))" id="pt"/>
    7
  6. <!-- 【3、拦截指定类的指定方法, 拦截时候一定要定位到方法】 -->
  7. <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.save(..))" id="pt"/>
  8.  
  9. <!-- 【4、拦截指定类的所有方法】 -->
  10. <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.*(..))" id="pt"/>

  11. <!-- 【5、拦截指定包,以及其自包下所有类的所有方法】 -->
  12. <aop:pointcut expression="execution(* com..*.*(..))" id="pt"/>

  13. <!-- 【6、多条件】 -->
  14. <!-- 或:|| or -->
  15. <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.save(..)) || execution(* com.shore.dao.impl.MessageDao.save(..))" id="pt" />
    <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.save(..)) or execution(* com.shore.dao.impl.MessageDao.save(..))" id="pt" />

  16. <!-- 且:&amp;&amp; and --> <!-- 语法虽然没错,但,没意义 -->
  17. <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.save(..)) &amp;&amp; execution(* com.shore.dao.impl.MessageDao.save(..))" id="pt" />
  18. <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.save(..)) and execution(* com.shore.dao.impl.MessageDao.save(..))" id="pt" />

  19. <!-- 【7、取非值:not ! 不拦截指定的规则,拦截除此之外的所有类的方法】 -->
  20. <aop:pointcut expression="!execution(* com.shore.dao.impl.UserDao.save(..))" id="pt"/>
    <!-- 注意not前必须有空格 -->
  21. <aop:pointcut expression=" not execution(* com.shore.dao.impl.UserDao.save(..))" id="pt"/>

2、实例

用到的jar包:

    

相关代码:

  1. //接口
  2. public interface IUserDao {
  3. public void save();
  4. }
  5.  
  6. //接口实现类
  7. public class UserDao implements IUserDao {
  8.  
  9. @Override
  10. public void save() { //3、执行业务方法
  11. System.out.println("3、保存用户成功!");
  12. }
  13. }

MessageDao 类(此类,没有实现任何接口)

  1. public class MessageDao {
  2. public void save() { //3、执行业务方法
  3. System.out.println("3、保存信息成功!");
  4. }
  5. }

Aop 类

  1. package com.shore.aop;
  2.  
  3. import org.aspectj.lang.ProceedingJoinPoint;
  4.  
  5. /**
  6. * @author DSHORE/2019-11-7
  7. *
  8. */
  9. public class Aop {
  10. //around:环绕; ProceedingJoinPoint:必须添加(执行)
  11. @SuppressWarnings("unused")
  12. private void around(ProceedingJoinPoint pjp) throws Throwable {
  13. System.out.println("2、环绕前....");
  14. pjp.proceed(); // 执行目标方法(业务代码)
  15. System.out.println("5、环绕后....");
  16. }
  17.  
  18. public void begin() {
  19. System.out.println("1、开启事务......");
  20. }
  21.  
  22. public void commit() {
  23. System.out.println("6、提交事务......");
  24. }
  25.  
  26. public void afterReturning() {
  27. System.out.println("4、afterReturning(),返回消息");
  28. }
  29.  
  30. //有异常,执行这个第四步;没有异常,则执行上面的第四步
  31. public void afterThrowing(){
  32. System.out.println("4、afterThrowing(),返回异常消息");
  33. }
  34. }

Spring 配置文件(beans.xml)

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns:tx="http://www.springframework.org/schema/tx"
  5. xsi:schemaLocation="
  6. http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/tx
  9. http://www.springframework.org/schema/tx/spring-tx.xsd
  10. http://www.springframework.org/schema/aop
  11. http://www.springframework.org/schema/aop/spring-aop.xsd">
  12.  
  13. <!-- dao类 -->
  14. <bean id="userDao" class="com.shore.dao.impl.UserDao"></bean>
  15. <bean id="messageDao" class="com.shore.dao.impl.MessageDao"></bean>
  16.  
  17. <!-- 注入切面类 -->
  18. <bean id="aop" class="com.shore.aop.Aop"></bean>
  19.  
  20. <aop:config>
  21. <!-- 配置切入点 -->
  22. <!-- 切入点表达式语法: -->
  23. <!-- 【1、拦截所有public方法】 --> <!-- 【第一个*是返回类型,第二个*是方法名 -->
  24. <!-- <aop:pointcut expression="execution(public * *(..))" id="pt" /> -->
  25.  
  26. <!-- 【2、拦截所有save开头的方法】 -->
  27. <!-- <aop:pointcut expression="execution(* save(..))" id="pt" /> -->
  28.  
  29. <!-- 【3、拦截指定类的指定方法, 拦截时候一定要定位到方法】 -->
  30. <!-- <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.save(..))" id="pt" /> -->
  31.  
  32. <!-- 【4、拦截指定类的所有方法】 -->
  33. <!-- <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.*(..))" id="pt" /> -->
  34.  
  35. <!-- 【5、拦截指定包,以及其自包下所有类的所有方法】 -->
  36. <!-- <aop:pointcut expression="execution(* com..*.*(..))" id="pt" /> -->
  37. <!-- <aop:pointcut expression="execution(* com..UserDao.*(..))" id="pt" /> -->
  38.  
  39. <!-- 6、多条件 -->
  40. <!-- 【(1)或:or ||】 -->
  41. <!-- <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.save(..)) or execution(* com.shore.dao.impl.MessageDao.save(..))" id="pt" /> -->
  42. <!-- 【(2)与:and &amp;&amp;】 -->
  43. <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.save(..)) and execution(* com.shore.dao.impl.MessageDao.save(..))" id="pt" />
  44.  
  45. <!-- 【7、否定:! not(not前后都需要空格)】 -->
  46. <!-- <aop:pointcut expression="!execution(* com.shore.dao.impl.UserDao.*(..))" id="pt" /> -->
  47. <aop:pointcut expression=" not execution(* com.shore.dao.impl.UserDao.*(..))" id="pt" />
  48.  
  49. <!-- 配置切面(切入点形成的类,切入点就是重复的代码/方法) -->
  50. <aop:aspect ref="aop">
  51. <!-- 1、开启事务。。。。。。 -->
  52. <aop:before method="begin" pointcut-ref="pt" />
  53. <!-- 6、提交事务 -->
  54. <aop:after method="commit" pointcut-ref="pt" />
  55. <!-- 环绕2/5 -->
  56. <aop:around method="around" pointcut-ref="pt" />
  57. <!-- 4、afterReturning -->
  58. <aop:after-returning method="afterReturning"
  59. pointcut-ref="pt" />
  60. <!-- 4、异常(程序出现异常,执行这个第四步;没有异常,则执行上面的第四步) -->
  61. <aop:after-throwing method="afterThrowing"
  62. pointcut-ref="pt" />
  63. </aop:aspect>
  64. </aop:config>
  65. </beans>

测试类

  1. package com.shore.test;
  2.  
  3. import org.junit.Test;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;
  6.  
  7. import com.shore.dao.IUserDao;
  8. import com.shore.dao.impl.MessageDao;
  9.  
  10. /**
  11. * @author DSHORE/2019-11-7
  12. *
  13. */
  14. public class MyTest {
  15. @Test
  16. public void testUserDao() {
  17. ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
  18. IUserDao userDao = (IUserDao) context.getBean("userDao");
  19. //$Proxy4 :class com.sun.proxy.$Proxy4
  20. System.out.println("这个相当于动态代理$Proxy4:"+userDao);//返回值:com.shore.dao.impl.UserDao@73aecc3a
  21. userDao.save();
  22. System.out.println("=============== 分割线 ===============");
  23.  
  24. MessageDao messageDao = (MessageDao) context.getBean("messageDao");
  25. System.out.println("这个相当于Cglib子类代理:"+messageDao);//返回值:com.shore.dao.impl.MessageDao@15412e75
  26. messageDao.save();
  27. }
  28. }

上方实例,切入点出代码,详细解析:

  1、拦截所有public方法

  1. <!-- 【1、拦截所有public方法】 --> <!-- 第一个*是返回值类型,第二个*是方法名;两个..表示可以是两个或者是多个参数 -->
  2. <aop:pointcut expression="execution(public * *(..))" id="pt" />

运行结果图:

解析:

从上面的项目截图以及相关代码,可以看出:只有三个public 方法,Aop类中的不算,因为他是切面类。故,上面红框中的结果,大家不难理解。没有红框的两处代码,是对IUserDao类进行拦截,输出两遍,是因为测试类,调用它两遍。

2、拦截所有save开头的方法

  1. <!-- 【2、拦截所有save开头的方法】 --> <!-- 第一个*是返回类型,两个..表示可以是两个或者是多个参数 -->
  2. <aop:pointcut expression="execution(* save(..))" id="pt" />

运行结果图:

解析省略(看结果图中的红色文字)

3、拦截指定类的指定方法, 拦截时候一定要 定位到方法

  1. <!-- 【3、拦截指定类的指定方法, 拦截时候一定要定位到方法】 --> <!-- 第一个*是返回类型,两个..表示可以是两个或者是多个参数 -->
  2. <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.save(..))" id="pt" />

运行结果图:

解析:

从上面的代码和结果图,可以看出,这里只对UserDao类中的save方法进行拦截。虽然MessageDao类中的save方法也运行了,但是,没有开启事务,也没提交事务,故不会生效。

4、拦截指定类的所有方法

  1. <!-- 【4、拦截指定类的所有方法】 --> <!-- 第一个*是返回值类型,第二个*是方法名;两个..表示可以是两个或者是多个参数 -->
  2. <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.*(..))" id="pt" />

运行结果图:

解析省略(和上面第3点一样,UserDao类中,有多少个方法,就执行多少个,结果类似)

5、拦截指定包,以及其自包下所有类的所有方法

  1. <!-- 【5、拦截指定包,以及其自包下所有类的所有方法】 -->
  2. <aop:pointcut expression="execution(* com..*.*(..))" id="pt" /><!-- 这几个*分别是 返回类型、com包下的所有类、指定类下的所有方法 -->
    <aop:pointcut expression="execution(* com..UserDao.*(..))" id="pt" />

运行结果图:

解析省略(和上面的测试结果类似)

6、多条件

  1. <!-- 6、多条件 -->
  2. <!-- 【(1)或:or ||】 -->
  3. <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.save(..)) or execution(* com.shore.dao.impl.MessageDao.save(..))" id="pt" />
  4. <!-- 【(2)与:and &amp;&amp;】 -->
  5. <aop:pointcut expression="execution(* com.shore.dao.impl.UserDao.save(..)) and execution(* com.shore.dao.impl.MessageDao.save(..))" id="pt" />

运行结果图:

解析省略(看结果图中的红色文字)

7、否定: !  not(注意:not前后都需要空格)

  1. <!-- 【7、否定: ! not(not前后都需要空格)】 -->
  2. <aop:pointcut expression="!execution(* com.shore.dao.impl.UserDao.*(..))" id="pt" />
  3. <aop:pointcut expression=" not execution(* com.shore.dao.impl.UserDao.*(..))" id="pt" />

运行结果图:

解析省略(看结果图中的红色文字)

本文总结: 经测试结果显示,做修饰符(public/private/protected)和否定(!  not)测试时,连接口类都一起拦截。除这两种以外,只要是指定了包名、类名、方法名的 等等,都不会再去拦截接口类。

原创作者:DSHORE

作者主页:http://www.cnblogs.com/dshore123/

原文出自:https://www.cnblogs.com/dshore123/p/11823849.html

欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!

Java进阶知识22 Spring execution 切入点表达式的更多相关文章

  1. Java进阶知识25 Spring与Hibernate整合到一起

    1.概述 1.1.Spring与Hibernate整合关键点 1) Hibernate的SessionFactory对象交给Spring创建.    2) hibernate事务交给spring的声明 ...

  2. Java进阶知识24 Spring的事务管理(事务回滚)

    1.事务控制概述   1.1.编程式事务控制         自己手动控制事务,就叫做编程式事务控制.         Jdbc代码: connection.setAutoCommit(false); ...

  3. Java进阶知识21 Spring的AOP编程

    1.概述 Aop:(Aspect Oriented Programming)面向切面编程          功能: 让关注点代码与业务代码分离! 关注点:重复代码就叫做关注点:切面: 关注点形成的类, ...

  4. Java进阶知识23 Spring对JDBC的支持

    1.最主要的代码 Spring 配置文件(beans.xml) <!-- 连接池 --> <bean id="dataSource" class="co ...

  5. Java进阶知识20 Spring的代理模式

    本文知识点(目录): 1.概念  2.代理模式      2.1.静态代理      2.2.动态代理      2.3.Cglib子类代理 1.概念 1.工厂模式  2. 单例模式 代理(Proxy ...

  6. Java进阶知识17 Spring Bean对象的创建细节和创建方式

    本文知识点(目录): 1.创建细节         1) 对象创建: 单例/多例         2) 什么时候创建?         3)是否延迟创建(懒加载)         4) 创建对象之后, ...

  7. Java进阶知识15 Spring的基础配置详解

    1.SSH各个的职责 Struts2:是web框架(管理jsp.action.actionform等).Hibernate:是ORM框架,处于持久层.Spring:是一个容器框架,用于配置bean,并 ...

  8. Java进阶知识18 Spring对象依赖关系的几种写法

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  9. Java进阶知识16 Spring创建IOC容器的两种方式

    1.直接得到 IOC 容器对象 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app ...

随机推荐

  1. pandas之分组计算笔记

    分组计算三部曲:拆分-->应用-->合并 分组:就是按照行或列把相同索引的部分分到一起 分组的关键词为groupby,分组后我们就可以对每组数据进行同一操作,返回的是每组数据分别计算后的结 ...

  2. JVM 利用 VisualVM 对高并发项目进行性能分析(转)

    出处:  深入理解 Java 虚拟机-如何利用 VisualVM 对高并发项目进行性能分析 前面在学习JVM的知识的时候,一般都需要利用相关参数进行分析,而分析一般都需要用到一些分析的工具,因为一般使 ...

  3. java 用户线程和守护线程

    在Java中通常有两种线程:用户线程和守护线程(也被称为服务线程)通过Thread.setDaemon(false)设置为用户线程通过Thread.setDaemon(true)设置为守护线程线程属性 ...

  4. odoo——日历的一对多与多对一

    # model文件 # -*- coding: utf-8 -*- from odoo import api, fields, models class TodoTestYear(models.Mod ...

  5. hdu 2473 并差集的删除操作

    虚拟数组 待定/.#include<iostream> #include<algorithm> #include<set> using namespace std; ...

  6. JS OOP -03 JS类的实现

    JS类的实现: a.理解类的实现机制 b.使用prototype对象定义类成员 c.一种JS类的设计模式 a.理解类的实现机制 在JS中可以使用function关键字来定义一个类. 添加类的成员,在函 ...

  7. Eclipse syntax coloring java xml 语法 样式

    自定义java源文件的编码样式,包括关键词等等的样式和颜色等,可以一边调下面就能看到样式效果,这是我自己一个个设置好的如图 自定义xml文件编辑器的样式格式,其实我装了sublime 但是 eclip ...

  8. 什么?在SAP中国研究院里还需要会PHP开发?

    请原谅Jerry这篇文章的题目有"标题党"的嫌疑. 没错,至少SAP成都研究院的部分团队如此,比如Jerry目前就职的SAP成都研究院数字创新空间. 之前Jerry的文章, 曾经提 ...

  9. Linux——CentOS7安装gcc编译器详解 查看内核版本

    [root@localhost ~]# uname -a Linux localhost.localdomain 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:3 ...

  10. 【Hibernate】抓取策略

    一.区分延迟和立即检索 二.类级别检索和关联级别检索 一.区分延迟和立即检索 立即检索: 当执行某行代码的时候,马上发出SQL语句进行查询. get() 延迟检索: 当执行某行代码的时候,不会马上发出 ...