Spring-AOP @AspectJ进阶之命名切点
概述
在前面所举的例子中,比如
@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
- 点赞
- 收藏
- 关注作者
评论(0)