Spring-AOP @AspectJ切点函数之execution()

举报
小工匠 发表于 2021/09/09 23:52:58 2021/09/09
【摘要】 文章目录 概述通过execution()定义切点的不同方式通过方法签名定义切点通过类定义切点通过类包定义切点通过方法入参定义切点 实例 概述 execution()是最常用的切点函数,...

概述

execution()是最常用的切点函数,语法如下

execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)

  
 
  • 1

其中:返回类型模式、方法名模式、参数模式是必选项。


通过execution()定义切点的不同方式

下面我们通过各种实例来理解如何使用execution()

通过方法签名定义切点

  • execution(public * *(..)) 匹配所有目标类的public方法。 第一个*代表返回类型,第二个*代表方法名,而..代表任意入参的方法

  • execution(* *To(..)) 匹配目标类所有以To为后缀的方法。 第一个*代表返回类型,而*To代表任意以To为后缀的方法。


通过类定义切点

  • execution(* com.xgj.aop.spring.advisor.aspectJ.function.execution.classpoint.Cleaner.*(..))匹配Cleaner接口的所有方法(包括实现类中覆写的方法), 第一个 * 代表返回任意类型 ,...Cleaner.*代表Cleaner接口中的所有方法

  • execution(* com.xgj.aop.spring.advisor.aspectJ.function.execution.classpoint.Cleaner.*(..))匹配Cleaner接口及其所有实现类的方法,不但匹配实现类中覆写的方法,也包括实现类中不在接口中定义的方法


通过类包定义切点

在类名模式串中,.*表示包下的所有类,..*表示包、子孙包下的所有类

  • execution(* com.xgj.*(..))匹配com.xgj包下所有类的所有方法

  • execution(* com.xgj..*(..))匹配com.xgj包、子孙包下所有类的所有方法.比如 com.xgj.dao ,com.xgj.service,com.xgj.dao.user包下所有类的所有方法都匹配。 ..出现在类名中时,必须后面跟*表示子孙包下的所有类。

  • execution(* com..*Dao.find*(..))匹配包名前缀为com的任何包下类名后缀为Dao的方法,方法名必须以find为前缀, 比如com.xgj.UserDao#findUserById()方法都是匹配切点。


通过方法入参定义切点

切点表达式中的方法入参部分比较复杂,可以使用*..通配符。 其中 *表示任意参数类型的参数, 而..表示任意类型的参数且参数个数不限。

  • execution(* joke(String,int))匹配joke(String,int)方法,且joke方法的第一个入参是String,第二个入参是int。 比如 匹配 SmartSeller#joke(String ,int)方法。 如果方法中的入参类型是java.lang包下的,这可以直接使用类名,否则必须使用全限定类名,比如 joke(java.util.List,int)

  • execution(* joke(String,*))匹配目标类中的joke()方法,该方法第一个入参为String,第二个入参为任意类型。 比如 joke(String s1, String s2)和joke(String s1,double d)都匹配,但是 joke(String s1, String s2,double d3)不匹配

  • execution(* joke(String,..))匹配目标类中的joke方法,该方法的第一个入参为String,后面可以有任意个入参且入参类型不限。 比如 joke(String s1),joke(String s1,String s2)和joke(String s1,double d2,String s3)都匹配。

  • execution(* joke(Object+))匹配目标类中的joke()方法,方法拥有一个入参,且入参是Object类型或该类的子类。 它匹配joke(String s1) 和joke(Client c) . 如果定义的切点是execution(* joke(Object)) ,则只匹配joke(Object object)而不匹配joke(String s1) 或者joke(Client c)


实例

代码已托管到Github—> https://github.com/yangshangwei/SpringMaster

仅以通过方法签名定义切点为例子,其余场景请参考https://github.com/yangshangwei/SpringMaster, 亲测通过。

execution(* com.xgj.aop.spring.advisor.aspectJ.function.execution.classpoint.Cleaner.*(..))

这里写图片描述

package com.xgj.aop.spring.advisor.aspectJ.function.execution;

public class NaiveWaiter {

	/**
	 * public方法,演示execution(public * *(..)),能匹配到
	 */
	public void greetTo(String clientName) {
		System.out.println("NaiveWaiter greet to " + clientName);
	}

}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
package com.xgj.aop.spring.advisor.aspectJ.function.execution;

public class SmartSeller {

	/**
	 * public方法,演示execution(public * *(..)),能匹配到
	 */
	public void sell(String goods) {
		System.out.println("SmartSeller sells " + goods);
	}

	/**
	 * 
	 * 
	 * @Title: smileTo
	 * 
	 * @Description: 非public方法,演示execution(public * *(..)),不能匹配到
	 * 
	 * @param clientName
	 * 
	 * @return: void
	 */
	protected void smileTo(String clientName) {
		System.out.println("SmartSeller simles to " + clientName);
	}

}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

切面

package com.xgj.aop.spring.advisor.aspectJ.function.execution;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

/**
 * 
 * 
 * @ClassName: ExecutionPublicAspect
 * 
 * @Description: TODO
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年8月27日 下午1:47:55
 */

@Aspect
public class ExecutionPublicAspect {

	@Before("execution(public * *(..))")
	public void crossCuttingLogic() {
		System.out.println("织入前置增强,横切逻辑code");
	}

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- 使用基于Schema的aop命名空间进行配置 -->
 

<!-- 基于@AspectJ切面的驱动器 -->
<aop:aspectj-autoproxy/>
 
<!-- 目标Bean -->
<bean id="smartSeller" class="com.xgj.aop.spring.advisor.aspectJ.function.execution.SmartSeller"/>
<bean id="naiveWaiter" class="com.xgj.aop.spring.advisor.aspectJ.function.execution.NaiveWaiter"/>
<!-- 使用了@AspectJ注解的切面类 -->
<bean class="com.xgj.aop.spring.advisor.aspectJ.function.execution.ExecutionPublicAspect"/>

</beans>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

测试类

package com.xgj.aop.spring.advisor.aspectJ.function.execution;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 
 * 
 * @ClassName: ExecutionPublicAspectTest
 * 
 * @Description: execution(public * *(..)) 测试类
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年8月27日 下午1:52:25
 */
public class ExecutionPublicAspectTest {

	@Test
	public void test() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"com/xgj/aop/spring/advisor/aspectJ/function/execution/conf-execution.xml");

		SmartSeller smartSeller = (SmartSeller) ctx.getBean("smartSeller");
		// sell方法是public,会织入前置增强中的横切逻辑
		smartSeller.sell("bread");
		// smileTo方法是protec,不会织入前置增强中的横切逻辑
		smartSeller.smileTo("XiaoGongJiang");

		NaiveWaiter naiveWaiter = (NaiveWaiter) ctx.getBean("naiveWaiter");
		// greetTo方法是public,会织入前置增强中的横切逻辑
		naiveWaiter.greetTo("XiaoGongJiang");

	}

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

运行结果

2017-08-29 00:00:39,395  INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@24b9371e: startup date [Tue Aug 29 00:00:39 BOT 2017]; root of context hierarchy
2017-08-29 00:00:39,514  INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/aspectJ/function/execution/conf-execution.xml]
织入前置增强,横切逻辑code
SmartSeller sells bread
SmartSeller simles to XiaoGongJiang
织入前置增强,横切逻辑code
NaiveWaiter greet to XiaoGongJiang


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

文章来源: artisan.blog.csdn.net,作者:小小工匠,版权归原作者所有,如需转载,请联系作者。

原文链接:artisan.blog.csdn.net/article/details/77627825

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。