AspectJ切面自定义注解实现参数分组校验——基础概念(2)

AspectJ切面自定义注解实现参数分组校验——基础概念(2)

    • 一、环境
    • 二、创建AspectJ
    • 2-1.基础概念
    • 2-2.Pointcut规则表达式
      • 2-3.切点标志符pointcut designator (PCD)
        • 1)execution
        • 2)within
        • 3)this和target
        • 4)args
        • 5)@target
        • 6)@args
        • 7)@within
        • 8)@annotation
      • 2-4.Pointcut规则表达式合并符号
      • 2-5.Advice通知
        • 1)启用Advice通知
        • 2)Before通知
        • 3)After通知
        • 4)Around通知

一、环境

maven需要引入依赖,aspectjweaver。

<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version>
</dependency>

二、创建AspectJ

2-1.基础概念

AspectJ提供了面向切面编程的实现,AspectJ有三个核心概念:

Join Point
Advice
Pointcut

Aspect(切面): 通过横切多个对象来做模块化的关联,每个切面侧重一个特定的横切功能。

Join point(执行点): 脚本执行过程中的一个点,例如方法的执行或属性的访问。

Advice(通知): 切面在特定执行点采取的行动。

Pointcut(与执行点相切的点): 使用规则表达式与执行点相切的点。advice通过pointcut的规则表达式,可在任意与执行点相切的点运行。

2-2.Pointcut规则表达式

Pointcut注解的源码,

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Pointcut {/*** @return the pointcut expression* We allow "" as default for abstract pointcut*/String value() default "";/*** When compiling without debug info, or when interpreting pointcuts at runtime,* the names of any arguments used in the pointcut are not available.* Under these circumstances only, it is necessary to provide the arg names in * the annotation - these MUST duplicate the names used in the annotated method.* Format is a simple comma-separated list.* * @return argNames the argument names (should match those in the annotated method)*/String argNames() default "";
}

Pointcut规则表达式可以是@pointcut注解的value。

2-3.切点标志符pointcut designator (PCD)

1)execution

最主要的Spring PCD是execution,通过method的执行点切入。

@Pointcut("execution(public String com.pingpongx.pointcutadvice.dao.InboundDao.findById(Long))")

上述的示例,InboundDao类的findById方法作为切点。但是这种方式不够灵活。

可以使用通配符,使规则表达式能表达的Pointcut更灵活。

@Pointcut("execution(* com.pingpongx.pointcutadvice.dao.InboundDao.*(..))")

第一个通配符*表示任意的return的结果。

第二个通配符*表示任意的方法名称。

第三个(..)表示任意个数的参数(包含0个)。

2)within

通过某种type的执行点切入。

@Pointcut("within(com.pingpongx.pointcutadvice.dao.InboundDao)")

当然也可以是某个package或者sub-package里面的任意类型。

@Pointcut("within(com.pingpongx..*)")

3)this和target

this limits matching to join points where the bean reference is an instance of the given type, while target limits matching to join points where the target object is an instance of the given type.

this在Spring AOP创建基于cglib的代理时有效,target在创建基于jdk的代理时使用。

假设targetXxxDao实现了一个接口

public class XxxDao implements YyyDao {...
}

上述例子,Spring AOP会使用基于jdk代理,因此需要使用target,因为代理的对象会是Proxy类的实例,且实现了YyyDao接口。

@Pointcut("target(com.pingpongx.pointcutadvice.dao.YyyDao)")

换言之,如果XxxDao没有实现任何接口,或者proxyTargetClass的属性是true,那么被代理的对象会是XxxDao的子类,需要使用this

@Pointcut("this(com.pingpongx.pointcutadvice.dao.XxxDao)")

4)args

通过特定方法的参数作为执行点切入。

@Pointcut("execution(* *..find*(Long))")

如果需要任意个数参数,但保证一个参数是Long类型。

@Pointcut("execution(* *..find*(Long,..))")

5)@target

执行切入点是执行对象的类具有给定类型的注解。

@Pointcut("@target(org.springframework.stereotype.Repository)")

6)@args

执行切入点是传递的实际参数是运行时类型,且具有给定类型的注释。

比如,追溯所有方法,方法满足接收的bean参数具备@Entity注解。

@Pointcut("@args(com.pingpongx.pointcutadvice.annotations.Entity)")
public void methodsAcceptingEntities() {}

要访问参数,我们应该为通知提供一个 JoinPoint 参数。

@Before("methodsAcceptingEntities()")
public void logMethodAcceptionEntityAnnotatedBean(JoinPoint jp) {logger.info("Accepting beans with @Entity annotation: " + jp.getArgs()[0]);
}

7)@within

执行切入点是具有给定注解的类型内的类型。

@Pointcut("@within(org.springframework.stereotype.Repository)")

等价于

@Pointcut("within(@org.springframework.stereotype.Repository *)")

8)@annotation

执行切入点是执行点的主体具有给定的注解。

@Pointcut("@annotation(com.pingpongx.pointcutadvice.annotations.Loggable)")
public void loggableMethods() {}
@Before("loggableMethods()")
public void logMethod(JoinPoint jp) {String methodName = jp.getSignature().getName();logger.info("Executing method: " + methodName);
}

2-4.Pointcut规则表达式合并符号

支持&&||操作符。

@Pointcut("@target(org.springframework.stereotype.Repository)")
public void repositoryMethods() {}@Pointcut("execution(* *..create*(Long,..))")
public void firstLongParamMethods() {}@Pointcut("repositoryMethods() && firstLongParamMethods()")
public void entityCreationMethods() {}

2-5.Advice通知

Advicearoundbeforeafter

1)启用Advice通知

对于configuration类使用@EnableAspectJAutoProxy注解,对于component类使用@Aspect注解。

2)Before通知

通知执行在执行点之前。除非抛出异常,否则它不会阻止它通知的方法的继续执行。

3)After通知

在切点的方法执行后执行,无论是否引发异常。

4)Around通知

ProceedingJoinPoint参数控制before和after功能效果,pjp.proceed()执行前是before,pjp.proceed()执行后是after,Object retval = pjp.proceed();return retval;是结束(或者抛出异常)。如果没有进行retval接收,直接return pjp.proceed();,就没有after了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

5230主题下载

最近朋友买了新手机&#xff0c;可是她又是电脑白痴&#xff0c;告诉她要她用百度搜&#xff0c;硬是没找到&#xff0c;百般无奈我千挑万选&#xff0c;找到了这个网站&#xff0c;让方便也同样带给同样不知道怎么用百度的朋友了5230主题下载网址&#xff1a;http://d.958shop…

AspectJ切面自定义注解实现参数分组校验——代码实现(3)

AspectJ切面自定义注解实现参数分组校验——代码实现&#xff08;3&#xff09;一、环境1-1.备注二、代码实现2-1.注解定义2-2.组定义2-3.constraints使用2-4.切面定义2-5.复用ValidatorFactory2-6.单测校验2-7.说明一、环境 springbootmaven <dependency><groupId&…

solaris下修改 IPMP 配置

使用 IPMP 配置文件 /etc/default/mpathd 为 IPMP 组配置以下系统范围的参数。 FAILURE_DETECTION_TIME TRACK_INTERFACES_ONLY_WITH_GROUPS FAILBACK 如何配置 /etc/default/mpathd 文件 在具有 IPMP 组配置的系统上&#xff0c;承担主管理员角色或成为超级用户。 主管理员角色…

电力自动化及继电保护实验室规章制度

为了按时完成电力自动化及继电保护实验&#xff0c;确保实验时人身安全与设备安全&#xff0c;要严格遵守如下规定的安全操作规程 一、 仔细阅读实验指导书内容&#xff0c;严格按实验指导书中的步骤来做试验。 二、 实验时&#xff0c;人体不可接触带电线路。 三、 接线或拆线…

主板跳线连接技巧图解

作为一名新手&#xff0c;要真正从头组装好自己的电脑并不容易&#xff0c;也许你知道CPU应该插哪儿&#xff0c;内存应该插哪儿&#xff0c;但遇到一排排复杂跳线的时候&#xff0c;很多新手都不知道如何下手。 钥匙开机其实并不神秘 还记不记得你第一次见到装电脑的时候…

几个不同的概念

站点 虚拟目录2个是不同德概念。站点需要应用程序池去生效。转载于:https://blog.51cto.com/vaxvax0000/390912

VMWARE双机安装说明

详见附件。 开始创建第一台机器&#xff1a;WIN2003 NODE1这里虚拟硬盘可以尽量选择大点,然后点“完成”进行创建就OK了。配置NODE1&#xff1a;把内存调整到256M以上&#xff0c;然后点“Add”增加一块网卡&#xff1a;网卡添加完后&#xff0c;再点“Add” 添加共享磁盘&…

GridView 中 Bind和Eval的区别详解

Eval()方法在运行时使用反射执行后期绑定计算&#xff0c;因此与标准的ASP.NET数据绑定方法bind相比&#xff0c;会导致性能明显下降。它一般用在绑定时需要格式化字符串的情况下。多数情况尽量少用此方法 Eval 方法是静态&#xff08;只读&#xff09;方法&#xff0c;该方法采…

为什么每个线程都需要创建一个栈?

有四个函数A、B、C、D&#xff0c;地址分别为100、200、300、400&#xff1b;有两个线程同时执行&#xff1b; 1&#xff09;假如只有一个栈 函数A在线程1中执行的时候&#xff0c;调用了函数B&#xff0c;将函数A中下一条指令的地址入栈&#xff08;104&#xff09;&#xff…

创建线程时,需要创建的内容

请参看文献&#xff1a;线程调度&#xff0c;这样就能明白为什么需要有TCB&#xff0c;栈等&#xff1b; 创建线程时&#xff0c;需要初始化的参数&#xff1a; void ThreadCreate(A){TCB *tcbmalloc(); //申请一段内存作为TCB* stackmalloc(); //申请一段内存作为栈* st…

莎士比亚,肯尼迪总统,孔子,奥巴马总统,马克吐温,梵高,比尔盖茨等13位名人阔谈微博(中英双语版本)...

2019独角兽企业重金招聘Python工程师标准>>> 作者: ganzhijie 发表于 2010-09-02 10:11 原文链接 阅读: 21 评论: 0 John F. Kennedy-“Ask not what your twitter can do for you, ask what you can do for your twitter.”肯尼迪总统-“不要问你的微博能为你做些什…

Scala中=gt;的用法

1.匿名函数 (x: Int) > x 1这一部分就是一个匿名函数&#xff0c;我这里使用了一个变量anonymousFun代替了这个匿名函数方便测试调用&#xff1b;>左边是参数和参数类型&#xff0c;而>右边是函数体&#xff0c;并没有函数名。 val anonymousFun (x: Int) > x …

sql server 游标的使用

1 --zhxia2 DECLAREusernameVARCHAR(20),flagBIT,ncountint3 DECLAREmycursor CURSORFOR--声明游标4 SELECTuser_nameFROMRBAC_User5 OPENmycursor --打开游标6 SETflag07 SETncount08 WHILE(flag0)9 BEGIN10 SETncountncount111 FETCHmycursor INTOusername--循环读取游标12 I…

续——《RedHat/Fedora等非ubuntu的Linux系统星空极速netkeeper拨号上网 》

小补充&#xff0c;在上一篇转载的文章中《RedHat/Fedora等非ubuntu的Linux系统星空极速netkeeper拨号上网》中提到&#xff5b;方法一&#xff0c;Debian下突破星空极速拨号用了一个“pon”命令&#xff0c;完整的拨号命令是“pon dsl-provider”&#xff0c;&#xff5d;&…

Java中Thread类的方法简介

1.新建线程 Thread t1 new Thread(); t1.start(); 新建线程&#xff0c;应该调用start()方法启动线程&#xff1b;如果直接调用run()方法&#xff0c;该方法也会执行&#xff0c;但会被当做一个普通的方法&#xff0c;在当前线程中顺序执行&#xff1b;而如果使用start()方法…

centos 本地化配置

2019独角兽企业重金招聘Python工程师标准>>> 最近使用svn更新的时候经常出现一些奇怪的错误。经过查询得知是本地化环境没有配置&#xff0c;导致的。记录以下解决方法。 本人环境&#xff1a;centos 5.x 错误现象&#xff1a; [Copy to clipboard]View Code ERRORs…

MySQL连接查询

1.分类 MySQL连接可以分为&#xff1a; 1&#xff09;内连接 2&#xff09;外连接 左外连接右外连接全外连接 3&#xff09;自然连接 自然内连接(NATURAL JOIN)自然左外连接(NATURAL LEFT JOIN)自然右外连接(NATURAL RIGHT JOIN) 4&#xff09;交叉连接 2.语法 SELECT…

IP编址(包括网络地址和广播地址)

1.总述 IP地址使用32位二进数表示&#xff0c;每一个主机或路由器的接口都有全局唯一的IP地址&#xff08;NAT是个例外&#xff09;&#xff0c;它由网络号(NetID)和主机号(HostID)组成&#xff0c;它可以分为五类&#xff0c;如下&#xff1a; 2.地址划分 1&#xff09;A…

JSP中 input type 用法

JSP中 input type 用法 Input表示Form表单中的一种输入对象&#xff0c;其又随Type类型的不同而分文本输入框&#xff0c;密码输入框&#xff0c;单选/复选框&#xff0c;提交/重置按钮等&#xff0c;下面一一介绍。 1&#xff0c;typetext 输入类型是text&#xff0c;这是我们…

java box unboxing

http://www.java2s.com/Tutorial/Java/0040__Data-Type/BoxingandUnboxing.htmBoxing and Unboxing1、Boxing refers to the conversion of a primitive to a corresponding wrapper instance, such as from an int toa java.lang.Integer. 2、Unboxing is the conversion of a…