Java Spring AOP之PointCut案例详解
作者:敲代码的小小酥 发布时间:2023-05-24 16:46:15
一、PointCut接口
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop;
/**
* Core Spring pointcut abstraction.
*
* <p>A pointcut is composed of a {@link ClassFilter} and a {@link MethodMatcher}.
* Both these basic terms and a Pointcut itself can be combined to build up combinations
* (e.g. through {@link org.springframework.aop.support.ComposablePointcut}).
*
* @author Rod Johnson
* @see ClassFilter
* @see MethodMatcher
* @see org.springframework.aop.support.Pointcuts
* @see org.springframework.aop.support.ClassFilters
* @see org.springframework.aop.support.MethodMatchers
*/
public interface Pointcut {
/**
* Return the ClassFilter for this pointcut.
* @return the ClassFilter (never {@code null})
*/
ClassFilter getClassFilter();
/**
* Return the MethodMatcher for this pointcut.
* @return the MethodMatcher (never {@code null})
*/
MethodMatcher getMethodMatcher();
/**
* Canonical Pointcut instance that always matches.
*/
Pointcut TRUE = TruePointcut.INSTANCE;
}
由源码可知,PointCut接口就是定义了两个元素,ClassFilter和MethodMatcher。PointCut接口就是为了获得这两个元素。换句话说,PointCut的功能,都包含在了这两个元素里。下面看这 两个元素源码。
二、ClassFilter接口
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop;
/**
* Filter that restricts matching of a pointcut or introduction to
* a given set of target classes.
*
* <p>Can be used as part of a {@link Pointcut} or for the entire
* targeting of an {@link IntroductionAdvisor}.
*
* <p>Concrete implementations of this interface typically should provide proper
* implementations of {@link Object#equals(Object)} and {@link Object#hashCode()}
* in order to allow the filter to be used in caching scenarios — for
* example, in proxies generated by CGLIB.
*
* @author Rod Johnson
* @see Pointcut
* @see MethodMatcher
*/
@FunctionalInterface
public interface ClassFilter {
/**
* Should the pointcut apply to the given interface or target class?
* @param clazz the candidate target class
* @return whether the advice should apply to the given target class
*/
boolean matches(Class<?> clazz);
/**
* Canonical instance of a ClassFilter that matches all classes.
*/
ClassFilter TRUE = TrueClassFilter.INSTANCE;
}
这个接口用来过滤要生成代理的类和给定的类是否匹配。
该接口的实现类应该提供正确的equals()方法和hashCode()方法,以便于能在缓存中使用。例如通过cglib生成的代理对象。(这句话什么意思,不理解)。
matches方法就是判断参数中的class类是否和切点定义的类相匹配。如果匹配,则生成代理对象,如果不匹配,则过滤掉。
三、MethodMatcher接口
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop;
import java.lang.reflect.Method;
/**
* Part of a {@link Pointcut}: Checks whether the target method is eligible for advice.
*
* <p>A MethodMatcher may be evaluated <b>statically</b> or at <b>runtime</b> (dynamically).
* Static matching involves method and (possibly) method attributes. Dynamic matching
* also makes arguments for a particular call available, and any effects of running
* previous advice applying to the joinpoint.
*
* <p>If an implementation returns {@code false} from its {@link #isRuntime()}
* method, evaluation can be performed statically, and the result will be the same
* for all invocations of this method, whatever their arguments. This means that
* if the {@link #isRuntime()} method returns {@code false}, the 3-arg
* {@link #matches(java.lang.reflect.Method, Class, Object[])} method will never be invoked.
*
* <p>If an implementation returns {@code true} from its 2-arg
* {@link #matches(java.lang.reflect.Method, Class)} method and its {@link #isRuntime()} method
* returns {@code true}, the 3-arg {@link #matches(java.lang.reflect.Method, Class, Object[])}
* method will be invoked <i>immediately before each potential execution of the related advice</i>,
* to decide whether the advice should run. All previous advice, such as earlier interceptors
* in an interceptor chain, will have run, so any state changes they have produced in
* parameters or ThreadLocal state will be available at the time of evaluation.
*
* <p>Concrete implementations of this interface typically should provide proper
* implementations of {@link Object#equals(Object)} and {@link Object#hashCode()}
* in order to allow the matcher to be used in caching scenarios — for
* example, in proxies generated by CGLIB.
*
* @author Rod Johnson
* @since 11.11.2003
* @see Pointcut
* @see ClassFilter
*/
public interface MethodMatcher {
/**
* Perform static checking whether the given method matches.
* <p>If this returns {@code false} or if the {@link #isRuntime()}
* method returns {@code false}, no runtime check (i.e. no
* {@link #matches(java.lang.reflect.Method, Class, Object[])} call)
* will be made.
* @param method the candidate method
* @param targetClass the target class
* @return whether or not this method matches statically
*/
boolean matches(Method method, Class<?> targetClass);
/**
* Is this MethodMatcher dynamic, that is, must a final call be made on the
* {@link #matches(java.lang.reflect.Method, Class, Object[])} method at
* runtime even if the 2-arg matches method returns {@code true}?
* <p>Can be invoked when an AOP proxy is created, and need not be invoked
* again before each method invocation,
* @return whether or not a runtime match via the 3-arg
* {@link #matches(java.lang.reflect.Method, Class, Object[])} method
* is required if static matching passed
*/
boolean isRuntime();
/**
* Check whether there a runtime (dynamic) match for this method,
* which must have matched statically.
* <p>This method is invoked only if the 2-arg matches method returns
* {@code true} for the given method and target class, and if the
* {@link #isRuntime()} method returns {@code true}. Invoked
* immediately before potential running of the advice, after any
* advice earlier in the advice chain has run.
* @param method the candidate method
* @param targetClass the target class
* @param args arguments to the method
* @return whether there's a runtime match
* @see MethodMatcher#matches(Method, Class)
*/
boolean matches(Method method, Class<?> targetClass, Object... args);
/**
* Canonical instance that matches all methods.
*/
MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
}
PointCut的一部分,用来判断方法是否需要进行增强。ClassFilter过滤需要生成代理的类。而这个类里,不是所有的方法都需要增强的,所以要通过MethodMatcher接口匹配出要增强的方法来。
MethodMatcher分为静态匹配和动态匹配。静态匹配是根据方法名匹配。动态匹配是根据参数进行匹配(不知道这么理解对不对)
MethodMatcher的实现类中,如果isRuntime()方法返回false,则使用静态匹配,无论参数是什么,只要方法名匹配,则都会进行增强。而且这个接口中带有3个参数的matches方法,即matches(java.lang.reflect.Method, Class, Object[])就永远不会执行。
实现类中,如果两个参数的matches方法返回true,且isRuntime()也返回true。那么在执行增强之前,会执行三个参数的matches方法,来判断这个增强是否要执行。
下面来看接口三个方法的注释:
boolean matches(Method method, Class<?> targetClass);
静态核对给定的方法是否需要增强。如果返回false。则不再会执行三个参数的matches方法。
boolean isRuntime();
当两个参数的matches方法返回true时,是否要执行三个参数的matches方法。该方法在AOP代理生成的时候执行,而不是每次调用代理方法之前执行。意思就是生成代理对象的时候,就已经判断好要不要执行三个参数的matches方法了。
boolean matches(Method method, Class<?> targetClass, Object... args);
该方法执行的时机是增强方法要执行之前,判断参数是否满足要求,如果满足,则执行增强。注意isRuntime方法是创建代理对象时就决定好的,而是否执行三个参数的matches方法是调用增强之前判断的。
总结
从上面的源码可以看出,PointCut就是起到过滤的作用,首先是过滤类,然后再过滤方法,筛选出需要加强的方法来。由接口可知,我们要将参数中的class或method进行比较,然后过滤,那么,和谁进行比较呢?要过滤的类和方法的规则存在哪里了呢?请看下回分解。
来源:https://blog.csdn.net/qq1309664161/article/details/120061132


猜你喜欢
- springboot:整合sa-token一、简介Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、Se
- 开篇Druid号称是Java语言中最好的数据库连接池,并且能够提供强大的监控和扩展功能。作为日常使用较多的数据库连接组件,纯粹个人兴趣研究下
- 问题描述我在接受 mq 消息的时候,需要做一个重试次数限制,如果超过 maxNum 就发邮件告警,不再重试。所以我需要对 consumer
- 滑动删除的部分主要包含两个部分, 一个是内容区域(用于放置正常显示的view),另一个是操作区域(用于放置删除按钮)。默认情况下,操作区域是
- 本文实例展示了C#基于TimeSpan实现倒计时效果的方法,比较实用的功能,对于初学者来说有一定的学习参考价值。具体实现方法如下:示例代码如
- 最近做了关于在Android设备上外接扫码的项目,在此记录一下关于Android USB扫码枪获取内容的问题首先我这边使用是USB HID的
- Android直播软件搭建实现背景颜色滑动渐变效果的相关代码一、介绍一下GradientDrawableGradientDrawable 支
- 目录时间轴是前端UI经常用到的效果,先看下效果图:实现一、借助 Container 中 decoration 属性,设置左侧的 border
- 在用java的io流读写文件时,总是被它的各种流能得很混乱,有40多个类,理清啦,过一段时间又混乱啦,决定整理一下!以防再忘Java输入/输
- 首先的效果图搜索到结果(这里我只是模拟数据,真正和服务器走得时候,返回来的数据都应该包含关键字的)模拟的没有搜索结果的界面具体实现在这插一句
- 在后端数据接口项目开发中,经常遇到返回的数据中有null值,导致前端需要进行判断处理,否则容易出现undefined的情况,如何便捷的将nu
- 场景描述在项目开发的过程中,需要修改调试的时候偶每次都需要重启项目浪费时间,下面是我整理的两种常用的两种方式方式一修改启动配置方式(主要针对
- 本文实例讲述了Java基于Tcp的基础聊天功能。分享给大家供大家参考,具体如下:最基础的聊天,用户端和服务器端每次说一句,而且严格规定了先后
- 本文实例讲述了Android编程之重力感应用法。分享给大家供大家参考,具体如下:重力感应主要是依靠手机的加速度传感器(acceleromet
- 在 Intellij Idea 中,我们需要设置 Settings 中的 Java Compiler 和 Project Structure
- 今天用scheduled写定时任务的时候发现定时任务一秒重复执行一次,而我的cron表达式为 * 0/2 * * * * 。在源码调试的过程
- 本文旨在用通俗的语言讲述枯燥的知识定时任务作为一种系统调度工具,在一些需要有定时作业的系统中应用广泛,如每逢某个时间点统计数据、在将来某个时
- 本文实例源自一个项目,其中需要调用本机的摄像头进行拍照,分享给大家供大家参考之用。具体步骤如下:硬件环境:联想C360一体机,自带摄像头编写
- 在我们的程序设计中,我们经常要加密一些特殊的内容,今天总结了几个简单的加密方法,分享给大家!如何用JAVA实现字符串简单加密解密?为保证用户
- SpringBoot是什么?Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初