Spring-AOP @AspectJ进阶之命名切点

举报
小工匠 发表于 2021/09/10 01:09:50 2021/09/10
【摘要】 文章目录 概述示例 概述 在前面所举的例子中,比如 @Before("within(com.xgj.aop.spring.advisor.aspectJAdvance.pointcutC...

文章目录

概述

在前面所举的例子中,比如

@Before("within(com.xgj.aop.spring.advisor.aspectJAdvance.pointcutComplex.*)"
			+ " && execution(* greetTo(..))")
	public void matchGreetTo() {
		System.out.println("matchGreetTo executed,some logic is here ");
	}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

切点直接声明在增强方法处,这种切点声明方式称为匿名切点,匿名切点只能在声明处使用。

如果希望在其它地方重用一个切点,我们可以通过@Pointcut注解以及切面类方法对切点进行命名


示例

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

package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;

import org.aspectj.lang.annotation.Pointcut;

/**
 * 
 * 
 * @ClassName: NamePoint
 * 
 * @Description: 如果希望在其它地方重用一个切点,我们可以通过@Pointcut注解以及切面类方法对切点进行命名
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年9月10日 下午11:13:45
 */
public class NamePoint{

	/**
	 * 
	 * 
	 * @Title: inPackage
	 * 
	 * @Description: 通过注解方法inPackage()对该切点进行命名,方法可视域
	 *               修饰符为private,表明该命名切点只能在本切面类中使用。
	 * 
	 * 
	 * @return: void
	 */
	@Pointcut("within(com.xgj.aop.spring.advisor.aspectJAdvance.namePoint)")
	private void inPackage() {

	};

	/**
	 * 
	 * 
	 * @Title: greetTo
	 * 
	 * @Description: 通过注解方法greetTo()对该切点进行命名,方法可视域
	 *               修饰符为protected,表明该命名切点可以在当前包中的切面 类、子切面类中中使用。
	 * 
	 * 
	 * @return: void
	 */
	@Pointcut("execution(* greetTo(..))")
	protected void greetTo() {

	}

	/**
	 * 
	 * 
	 * @Title: inPkgGreetTo
	 * 
	 * @Description: 引用命名切点定义的切点,本切点也是命名切点, 它对应的可视域为public
	 * 
	 * 
	 * @return: void
	 */
	@Pointcut("inPackage() and greetTo()")
	public void inPkgGreetTo() {

	}

}


  
 
  • 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
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

上面上述示例中定义了3个命名切点,命名切点的使用类方法作为切点的名称,此外方法的访问修饰符还控制了切点的可引用性,这种可引用性和类方法的可访问性相同,如private的切点只能在本类中引用,public的切点可以在任何类中引用。

命名切点仅利用方法名及访问修饰符的信息,所以习惯上,方法的返回类型为void,并且方法体为空。

我们可以通过下图更直观地了解命名切点的结构:

这里写图片描述

inPkgGreetTo()的切点引用了同类中的greetTo()切点,而inPkgGreetTo()切点可以被任何类引用。

你还可以扩展NamePoint类,通过类的继承关系定义更多的切点。 命名切点定义好后,就可以在定义切面时通过名称引用切点.

来看个示例

这里写图片描述

假设有两个业务类

package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;

import org.springframework.stereotype.Component;

/**
 * 
 * 
 * @ClassName: NaiveWaiter
 * 
 * @Description: @Component注解标注的bean
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年9月10日 下午11:55:00
 */

@Component
public class NaiveWaiter {

	public void greetTo(String clientName) {
		System.out.println("NaiveWaiter greetTo " + clientName);
	}

	public void serverTo(String clientName) {
		System.out.println("NaiveWaiter serverTo " + 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.aspectJAdvance.namePoint;

import org.springframework.stereotype.Component;

@Component
public class CuteWaiter {
	public void greetTo(String clientName) {
		System.out.println("CuteWaiter greetTo " + clientName);
	}

	public void serverTo(String clientName) {
		System.out.println("CuteWaiter serverTo " + clientName);
	}
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

切点命名复用上面那个切点,然后编写切面NamePointAspect

package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;

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

/**
 * 
 * 
 * @ClassName: NamePointTest
 * 
 * @Description: 使用@Aspect注解标注的切面,演示命名切点的使用
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年9月10日 下午11:42:39
 */

@Aspect
public class NamePointAspect {
	/**
	 * 
	 * 
	 * @Title: pkgGreetTo
	 * 
	 * @Description: 引用了NamePoint.inPkgGreetTo()切点
	 * 
	 * 
	 * @return: void
	 */
	@AfterReturning("NamePoint.inPkgGreetTo()")
	public void pkgGreetTo() {
		System.out.println("pkgGreetTo exectued ,some logic is here ");
	}

	/**
	 * 
	 * 
	 * @Title: pkgGreetToNotNaiveWaiter
	 * 
	 * @Description: 在复合运算中使用了命名切点
	 * 
	 * 
	 * @return: void
	 */
	@AfterReturning("!target(com.xgj.aop.spring.advisor.aspectJAdvance.namePoint.NaiveWaiter) && NamePoint.inPkgGreetTo()")
	public void pkgGreetToNotNaiveWaiter() {
		System.out
				.println("pkgGreetToNotNaiveWaiter() executed,some logic is here");
	}
}


  
 
  • 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
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

配置文件如下:

<?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"
	xmlns:context="http://www.springframework.org/schema/context"
	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
		http://www.springframework.org/schema/context 
       	http://www.springframework.org/schema/context/spring-context.xsd">

<!-- (1)声明Context命名空间以及Schema文件   (2)扫描类包以及应用注解定义的bean -->
<context:component-scan base-package="com.xgj.aop.spring.advisor.aspectJAdvance.namePoint"/>

<!-- 基于@AspectJ切面的驱动器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
 
<!-- 使用了@AspectJ注解的切面类 -->
<bean class="com.xgj.aop.spring.advisor.aspectJAdvance.namePoint.NamePointAspect"/>

</beans>


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

测试类

package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;

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

/**
 * 
 * 
 * @ClassName: NamePointAspectTest
 * 
 * @Description: 命名切点测试类
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年9月10日 下午11:56:50
 */

public class NamePointAspectTest {

	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"classpath:com/xgj/aop/spring/advisor/aspectJAdvance/namePoint/conf-namePoint.xml");

		CuteWaiter cuteWaiter = ctx.getBean("cuteWaiter", CuteWaiter.class);
		NaiveWaiter naiveWaiter = ctx.getBean("naiveWaiter", NaiveWaiter.class);

		naiveWaiter.greetTo("XiaoGongJiang");
		System.out.println("================");

		cuteWaiter.greetTo("XiaoGongJiang");
		System.out.println("================");

		naiveWaiter.serverTo("XiaoGongJiang");
		System.out.println("================");

		cuteWaiter.serverTo("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
  • 38

运行结果

2017-09-11 00:58:34,752  INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4888884e: startup date [Mon Sep 11 00:58:34 BOT 2017]; root of context hierarchy
2017-09-11 00:58:34,821  INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/aspectJAdvance/namePoint/conf-namePoint.xml]
NaiveWaiter greetTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here 
================
CuteWaiter greetTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here 
pkgGreetToNotNaiveWaiter() executed,some logic is here
================
NaiveWaiter serverTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here 
================
CuteWaiter serverTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here 
pkgGreetToNotNaiveWaiter() executed,some logic is here


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

可以看到NaiveWaiter greetTo 方法 没有织入第二个增强。

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

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

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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