简介

在Spring AOP概述中我们重点注意的是AOP的整体流程和Advice,简化了一些其他的东西,其中就有一些对灵活应用Spring AOP很重要的知识点,例如Pointcut表达式,下面就介绍一下Spring AOP的Pointcut表达式。

如果你对Pointcut表达式的作用还不是很了解,可以先看一下Spring AOP概述,也可以先了解一下匹配规则,后面会有一些具体的例子来帮助理解。

我们使用最多的就是execution表示了,下面就从execution表达式开始介绍吧。

注意:把designators翻译为表达式也许不太合适,所以不必纠结这个问题,只需要知道在看到Spring AOP中的designators知道对应的是个什么东西就可以了。管它是表达式还是指示器只是一个代称而已。

execution表达式

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

上面的就是execution表达式的格式,execution匹配的就是连接点(Joinpoint,一般是方法),看上面的表达式execution是固定的,方法的修饰符是可选的,返回类型是必须的,定义的全限类型也是可选的,名称是必须的,参数是必须的,这些都可以使用通配符。

任何的public方法

execution(public * *(..))

以set开始的方法

execution(* set*(..))

定义在cn.freemethod.business.pack.Say接口中的方法

execution(* cn.freemethod.business.pack.Say.*(..))

任何cn.freemethod.business包中的方法

execution(* cn.freemethod.business.*.*(..))

任何定义在com.xyz.service包或者其子包中的方法

execution(* cn.freemethod.business..*.*(..))

其他表达式

任何在com.xyz.service包中的方法

within(com.xyz.service.*)

任何定义在com.xyz.service包或者其子包中的方法

within(com.xyz.service..*)

任何实现了com.xyz.service.AccountService接口中的方法

this(com.xyz.service.AccountService)

任何目标对象实现了com.xyz.service.AccountService的方法

target(com.xyz.service.AccountService)

一般情况下代理类(Proxy)和目标类(Target)都实现了相同的接口,所以上面的2个基本是等效的。


有且只有一个Serializable参数的方法

args(java.io.Serializable)

只要这个参数实现了java.io.Serializable接口就可以,不管是java.io.Serializable还是Integer,还是String都可以。

目标(target)使用了@Transactional注解的方法

@target(org.springframework.transaction.annotation.Transactional)

目标类(target)如果有Transactional注解中的所有方法

@within(org.springframework.transaction.annotation.Transactional)

任何方法有Transactional注解的方法

@annotation(org.springframework.transaction.annotation.Transactional)

有且仅有一个参数并且参数上类型上有Transactional注解

@args(org.springframework.transaction.annotation.Transactional)

注意是参数类型上有Transactional注解,而不是方法的参数上有注解。

-- bean的名字为tradeService中的方法

 bean(simpleSay)
bean名字为simpleSay中的所有方法。

-- bean名字能匹配

bean(*Impl)
bean名字匹配*Impl的bean中的所有方法。

实例

这个实例是对Spring AOP概述中介绍的实例进行了扩展。当然下面给的实例也可以独立测试,最好是一个一个测试观察输出了验证,多个输出结果不够直观。

下面的图片是项目工程目录结构:

下面的代码列表因为比较多,只能展示部分代码。

--OtherPointcutAspect:

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.Aspect;

import org.springframework.stereotype.Component;

@Component

@Aspect

public class OtherPointcutAspect {

// @After("cn.freemethod.pointcut.OtherPointcut.argsSerializable()")

public void argsSerialize(){

System.out.println("OtherPointcutAspect argsSerialize after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.inBusinessPackage()")

public void inBusinessPackage(){

System.out.println("OtherPointcutAspect inBusinessPackage after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.inBusinessOrSubPackage()")

public void inBusinessOrSubPackage(){

System.out.println("OtherPointcutAspect inBusinessOrSubPackage after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.proxyImplementHaveResultBusinessInteferce()")

public void proxyImplementHaveResultBusinessInteferce(){

System.out.println("OtherPointcutAspect proxyImplementHaveResultBusinessInteferce after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.targetImplementBusinessInteferce()")

public void targetImplementBusinessInteferce(){

System.out.println("OtherPointcutAspect targetImplementBusinessInteferce after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.targetHaveTransactional()")

public void targetHaveTransactional(){

System.out.println("OtherPointcutAspect targetHaveTransactional after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.targetDeclareHaveTransactional()")

public void targetDeclareHaveTransactional(){

System.out.println("OtherPointcutAspect targetDeclareHaveTransactional after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.methodHaveTransactional()")

public void methodHaveTransactional(){

System.out.println("OtherPointcutAspect methodHaveTransactional after...");

}

@After("cn.freemethod.pointcut.OtherPointcut.argsHaveValueAnnotation()")
public void argsHaveTransactional(){
System.out.println("OtherPointcutAspect argsHaveValueAnnotation after...");
}

// @After("cn.freemethod.pointcut.OtherPointcut.beanName()")

public void beanName(){

System.out.println("OtherPointcutAspect beanName after...");

}

// @After("cn.freemethod.pointcut.OtherPointcut.matchBeanName()")

public void matchBeanName(){

System.out.println("OtherPointcutAspect matchBeanName after...");

}

}

上面是一个测试Pointcut表达式的切面,很多Advice都注释了,请为了从输出中直观的了解Pointcut表达式匹配到了什么方法(Joinpoint),请根据自己的需要测试的Pointcut表达式取消添加注释。

--ExecutionPointcutAspect:

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.AfterReturning;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.springframework.stereotype.Component;

@Component

@Aspect

public class ExecutionPointcutAspect {

@Before("cn.freemethod.pointcut.ExecutionPointcut.allPublicMethod()")
public void allPublicBefore(){
System.out.println("PointcutExpressionAspect allPublicBefore...");
} @After("cn.freemethod.pointcut.ExecutionPointcut.allStartSayMethod()")
public void sayAfter(){
System.out.println("PointcutExpressionAspect sayAfter...");
} @AfterReturning("cn.freemethod.pointcut.ExecutionPointcut.allInSayInterfaceMethod()")
public void allInSayInterfaceMethod(){
System.out.println("PointcutExpressionAspect allInSayInterfaceMethod...");
} @Before("cn.freemethod.pointcut.ExecutionPointcut.allInBusinessPackage()")
public void allInBusinessPackageBefore(){
System.out.println("PointcutExpressionAspect all business before...");
} @After("cn.freemethod.pointcut.ExecutionPointcut.allInBusinessOrSubPackage()")
public void allallInBusinessOrSubPackageAfter(){
System.out.println("PointcutExpressionAspect allallInBusinessOrSubPackageAfter...");
}

}

---ParamBean:

import org.springframework.transaction.annotation.Transactional;

@Transactional

public class ParamBean {

}

--HaveResultBusinessImpl:

import org.springframework.stereotype.Service;

import cn.freemethod.business.HaveResultBusiness;

@Service

public class HaveResultBusinessImpl implements HaveResultBusiness {

@Override
public Integer getResult(Integer div) {
System.out.println("HaveResultBusinessImpl getResult");
Integer result = 100 / div;
return result;
}

}

--IOtherPointcutImpl:

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import cn.freemethod.bean.ParamBean;

import cn.freemethod.business.pack.IOtherPointcut;

@Transactional

@Service

public class IOtherPointcutImpl implements IOtherPointcut {

@Override
public Integer printInteger(Integer arg) {
System.out.println("IOtherPointcutImpl printInteger");
return arg;
} @Override
public void withAnotationParam(ParamBean arg) {
System.out.println("IOtherPointcutImpl withAnotationParam");
}

}

--SimpleSay:

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import cn.freemethod.business.pack.Say;

@Transactional

@Service

public class SimpleSay implements Say {

@Override
public String sayChiness(String name) {
String result = "你好:" + name;
System.out.println(result);
return result;
} @Override
public String sayEnglish(String name) {
String result = "Hello " + name;
System.out.println(result);
return result;
} @Transactional
@Override
public String whatSay() {
System.out.println("what say");
return "what say";
}

}

--IOtherPointcut:

import cn.freemethod.bean.ParamBean;

public interface IOtherPointcut {

Integer printInteger(Integer arg);

void withAnotationParam(ParamBean arg);

}

--Say:

public interface Say {

String sayChiness(String name);

String sayEnglish(String name);

String whatSay();

}

--HaveResultBusiness:

public interface HaveResultBusiness {

Integer getResult(Integer div);

}

--AspectConfig:

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration

@EnableAspectJAutoProxy

@ComponentScan(basePackages = {"cn.freemethod"})

public class AspectConfig {

}

--ExecutionPointcut:

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

@Aspect

public class ExecutionPointcut {

@Pointcut("execution(public * *(..))")
public void allPublicMethod(){} @Pointcut("execution(* say*(..))")
public void allStartSayMethod(){} @Pointcut("execution(* cn.freemethod.business.pack.Say.*(..))")
public void allInSayInterfaceMethod(){} @Pointcut("execution(* cn.freemethod.business.*.*(..))")
public void allInBusinessPackage(){} @Pointcut("execution(* cn.freemethod.business..*.*(..))")
public void allInBusinessOrSubPackage(){}

}

--OtherPointcut :

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

@Aspect

public class OtherPointcut {

@Pointcut("within(cn.freemethod.business.impl.*)")
public void inBusinessPackage(){} @Pointcut("within(cn.freemethod.business..*)")
public void inBusinessOrSubPackage(){} @Pointcut("this(cn.freemethod.business.HaveResultBusiness)")
public void proxyImplementHaveResultBusinessInteferce(){} @Pointcut("target(cn.freemethod.business.HaveResultBusiness)")
public void targetImplementBusinessInteferce(){} @Pointcut("args(java.io.Serializable)")

// @Pointcut("args(java.lang.Integer)")

public void argsSerializable(){}

@Pointcut("@target(org.springframework.transaction.annotation.Transactional)")
public void targetHaveTransactional(){} @Pointcut("@within(org.springframework.transaction.annotation.Transactional)")
public void targetDeclareHaveTransactional(){} @Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")
public void methodHaveTransactional(){} @Pointcut("@args(org.springframework.transaction.annotation.Transactional)")
public void argsHaveValueAnnotation(){} @Pointcut("bean(simpleSay)")
public void beanName(){} @Pointcut("bean(*Impl)")
public void matchBeanName(){}

}

--AnnotationConfigStart:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.springframework.context.support.AbstractApplicationContext;

import cn.freemethod.business.HaveResultBusiness;

import cn.freemethod.business.pack.Say;

import cn.freemethod.config.AspectConfig;

public class AnnotationConfigStart {

public static void main(String[] args) {
AbstractApplicationContext context = new AnnotationConfigApplicationContext(AspectConfig.class);
HaveResultBusiness haveResultBusiness = context.getBean(HaveResultBusiness.class);
haveResultBusiness.getResult(100);
Say say = context.getBean(Say.class);
say.sayChiness("tim");
say.sayEnglish("tim");
say.whatSay();
context.close();
}

}

--PointcutExpressionStart:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.springframework.context.support.AbstractApplicationContext;

import cn.freemethod.bean.ParamBean;

import cn.freemethod.business.HaveResultBusiness;

import cn.freemethod.business.pack.IOtherPointcut;

import cn.freemethod.business.pack.Say;

import cn.freemethod.config.AspectConfig;

public class PointcutExpressionStart {

public static void main(String[] args) {
AbstractApplicationContext context = new AnnotationConfigApplicationContext(AspectConfig.class);
IOtherPointcut iOtherPointcut = context.getBean(IOtherPointcut.class);
iOtherPointcut.printInteger(new Integer(10));
iOtherPointcut.withAnotationParam(new ParamBean()); HaveResultBusiness haveResultBusiness = context.getBean(HaveResultBusiness.class);
haveResultBusiness.getResult(100); Say say = context.getBean(Say.class);
say.sayChiness("tim");
say.sayEnglish("tim");
say.whatSay();
context.close();
}

}

Spring AOP 之二:Pointcut注解表达式的更多相关文章

  1. spring AOP 之二:@AspectJ注解的3种配置

    @AspectJ相关文章 <spring AOP 之二:@AspectJ注解的3种配置> <spring AOP 之三:使用@AspectJ定义切入点> <spring ...

  2. 深入理解Spring AOP之二代理对象生成

    深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 ...

  3. Spring Aop(二)——基于Aspectj注解的Spring Aop简单实现

    转发地址:https://www.iteye.com/blog/elim-2394762 2 基于Aspectj注解的Spring Aop简单实现 Spring Aop是基于Aop框架Aspectj实 ...

  4. Spring AOP中使用@Aspect注解 面向切面实现日志横切功能详解

    引言: AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一 ...

  5. 【Spring AOP】Spring AOP之如何通过注解的方式实现各种通知类型的AOP操作进阶篇(3)

    一.切入点表达式的各种类型 切入点表达式的作用:限制连接点的匹配(满足时对应的aspect方法会被执行) 1)execution:用于匹配方法执行连接点.Spring AOP用户可能最经常使用exec ...

  6. spring AOP (使用AspectJ的注解方式 的aop实现) (6)

    目录 一.在 Spring 中启用 AspectJ 注解支持 二.AspectJ 支持 5 种类型的通知注解: 2.1.使用之前的 计算器接口和实现类 ArithmeticCalculator.jav ...

  7. Spring AOP(5)-- 注解

    applicationContext.xml <?xml version="1.0" encoding="UTF-8"?><beans xml ...

  8. Spring学习十五----------Spring AOP API的Pointcut、advice及 ProxyFactoryBean相关内容

    © 版权声明:本文为博主原创文章,转载请注明出处 实例: 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4. ...

  9. Spring AOP编程(二)-AOP实现的三种方式

    AOP的实现有三种方式: l         aop底层将采用代理机制进行实现. l         接口 + 实现类 :spring采用 jdk 的动态代理Proxy. l         实现类: ...

随机推荐

  1. 关于键盘事件-查询:有多个input框,任意一个支持enter键查询

    应用场景:同一个界面有多个input框支持任意一个Enter查询. 实现:在input框中添加onkeypress="函数名()". 函数里面编写对应键盘code值,在里面直接调用 ...

  2. 使用Flutter开发的抖音国际版

    简介 最近花了两天时间研究使用Flutter开发一个抖音国际版. 先上图,个人感觉使用Flutter开发app快得不要不要的额.  两天就基本可以开发个大概出来.   最主要是热更新,太方便实时调整U ...

  3. 30分钟快速上手Docker,看这篇就对了!

    一.历史演化 1.演化史 2.物理机时代 2.1.图解 一个物理机上安装操作系统,然后直接运行我们的软件.也就是说你电脑上直接跑了一个软件,并没有开虚拟机什么的,资源极其浪费. 2.2.缺点 部署慢 ...

  4. BZOJ1078 斜堆

    http://hzwer.com/5790.html  代码 http://www.cppblog.com/MatoNo1/archive/2013/03/03/192131.html  //原理讲解 ...

  5. Understanding REST and RESTful APIs

    Understanding REST and RESTful APIs If you've spent any amount of time with modern web development, ...

  6. 关于docker的常见使用命令

    1. Docker的启动与停止 systemctl命令是系统服务管理器指令 启动docker: systemctl start docker 停止docker: systemctl stop dock ...

  7. 关于Java两点需要更新的知识

    HashMap的初始容量 背景 很多人可以把HashMap的原理描述的很溜.比如JDK1.7之前,底层数据结构是数组+链表.JDK1.8之后,出于效率上的考虑,在数组长度大于64,链表长度大于8的时候 ...

  8. NodeJS——大汇总(一)(只需要使用这些东西,就能处理80%以上业务需求,全网最全node解决方案,吐血整理)

    一.前言 本文目标 本文是博主总结了之前的自己在做的很多个项目的一些知识点,当然我在这里不会过多的讲解业务的流程,而是建立一个小demon,旨在帮助大家去更加高效 更加便捷的生成自己的node后台接口 ...

  9. Netty学习笔记(二) - ChannelPipeline和ChannelHandler

    ChannelPipeline 和 ChannelHandler 是 Netty 重要的组件之一,通过这篇文章,重点了解这些组件是如何驱动数据流动和处理的. 一.ChannelHandler 在上一篇 ...

  10. 关于hexo-blog-encrypt插件输入密码后无响应的问题

    解决方案:更改网站为https协议 具体请查看: https://github.com/MikeCoder/hexo-blog-encrypt/issues/114