Spring AOP 之二:Pointcut注解表达式
简介
在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注解表达式的更多相关文章
- spring AOP 之二:@AspectJ注解的3种配置
@AspectJ相关文章 <spring AOP 之二:@AspectJ注解的3种配置> <spring AOP 之三:使用@AspectJ定义切入点> <spring ...
- 深入理解Spring AOP之二代理对象生成
深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 ...
- Spring Aop(二)——基于Aspectj注解的Spring Aop简单实现
转发地址:https://www.iteye.com/blog/elim-2394762 2 基于Aspectj注解的Spring Aop简单实现 Spring Aop是基于Aop框架Aspectj实 ...
- Spring AOP中使用@Aspect注解 面向切面实现日志横切功能详解
引言: AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一 ...
- 【Spring AOP】Spring AOP之如何通过注解的方式实现各种通知类型的AOP操作进阶篇(3)
一.切入点表达式的各种类型 切入点表达式的作用:限制连接点的匹配(满足时对应的aspect方法会被执行) 1)execution:用于匹配方法执行连接点.Spring AOP用户可能最经常使用exec ...
- spring AOP (使用AspectJ的注解方式 的aop实现) (6)
目录 一.在 Spring 中启用 AspectJ 注解支持 二.AspectJ 支持 5 种类型的通知注解: 2.1.使用之前的 计算器接口和实现类 ArithmeticCalculator.jav ...
- Spring AOP(5)-- 注解
applicationContext.xml <?xml version="1.0" encoding="UTF-8"?><beans xml ...
- Spring学习十五----------Spring AOP API的Pointcut、advice及 ProxyFactoryBean相关内容
© 版权声明:本文为博主原创文章,转载请注明出处 实例: 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4. ...
- Spring AOP编程(二)-AOP实现的三种方式
AOP的实现有三种方式: l aop底层将采用代理机制进行实现. l 接口 + 实现类 :spring采用 jdk 的动态代理Proxy. l 实现类: ...
随机推荐
- 终于明白了vue使用axios发送post请求时的坑及解决原理
前言:在做项目的时候正好同事碰到了这个问题,问为什么用axios在发送请求的时候没有成功,请求不到数据,反而是报错了,下图就是报错请求本尊 vue里代码如下: this.$http.post('/ge ...
- Java子父类间静态代码块、非静态代码块、构造方法的执行顺序
子类A继承父类B,A a=new A(); 正确的执行顺序是:父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A ...
- 贝叶斯优化(Bayesian Optimization)只需要看这一篇就够了,算法到python实现
贝叶斯优化 (BayesianOptimization) 1 问题提出 神经网咯是有许多超参数决定的,例如网络深度,学习率,正则等等.如何寻找最好的超参数组合,是一个老人靠经验,新人靠运气的任务. 穷 ...
- eclipse的Android一些问题
我最近在学习Android 用eclipse来写Android项目 一开始就遇到了许多的坑——但好在有老师们帮助.还有百度: 现在我开始总结: 1.安装eclipse,这个暂时不说,因为我还没遇到什么 ...
- 允许远程用户登录访问mysql
方法1.本地登入mysql,更改 “mysql” 数据库里的 “user” 表里的 “host” 项,将”localhost”改为”%” mysql -u root -proot use mysql; ...
- 关于pytest使用allure生成报告时,报一堆警告和缺少XX模块
因为最新的pytest 支持*.josn的用例报告,卸载旧的模块使用新的即可: 需要移除旧模块:pip uninstall pytest-allure-adaptor, 并安装:pip install ...
- JVM调优总结(八)-反思
垃圾回收的悖论 所谓“成也萧何败萧何”.Java的垃圾回收确实带来了很多好处,为开发带来了便利.但是在一些高性能.高并发的情况下,垃圾回收确成为了制约Java应用的瓶颈.目前JDK的垃圾回收算法,始终 ...
- [注]6W运营法则教你盘活社区内容运营
社区运营人员大体分为两种:一种是内容运营,这类人才基于产品,一般对文字以及对广告文案比较敏感:另外一种则是更多基于产品推广运营,前者需要把内容最大化地曝光,后者则是把产品推送给用户,两者的是相辅相成, ...
- python 05—字典
一.字典的键是唯一的 键:简单对象,例[字符串.整数.浮点数.bool值] list不能作为键,但可以作为值. 例: score = { '萧峰' : 95, '段誉' : 97, '虚竹' : 89 ...
- Java IO(五)字节流 FileInputStream 和 FileOutputStream
Java IO(五)字节流 FileInputStream 和 FileOutputStream 一.介绍 字节流 InputStream 和 OutputStream 是字节输入流和字节输出流的超类 ...