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
猜你喜欢
- System.out.print("\b") 会在控制台下往回删掉一个字符,如果你想回删多个字符就打印多个 "
- 今天有同事用swagger2开发时,有一方法返回Map<String,List<Object>>出现无法解析错误。P
- 作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三
- 前言使用SpringBoot来开发项目相对于传统模式,要快速优雅许多,相信目前国内绝大部分web项目的开发还没有使用SpringBoot来做
- 每一个应用程序,其实都会有分享的需求,比如一键分享一篇文章或者一些活动到微博或者微信亦或者是twitter等社交平台,因为人类是社交动物,而
- 在做asp.net和unity进行http通信的时候,当unity客户端发出表单请求的时候,我要将他要请求的数据以json的格式返回给客户端
- Java是一种面向对象的编程语言,由Sun Microsystems公司在1995年的时候正式发布。直到今天,Java都一直是最受欢迎的编程
- 下载和上传附件、发送短信和发送邮件,都算是程序中很常用的功能,之前记录了文件的上传和下载还有发送短信,由于最近比较忙,邮件发送的功能就没有时
- 算法文章,总是带给我们无穷的思考和兴趣,一个问题,多种解决方法,看你如何去思考它,对于标题所引出的问题,我觉得,使用递归是比较有效的方法,当
- 完整代码已上传到GitHub。Web端体验地址:http://47.116.72.33/(只剩一个月有效期)apk下载地址:https://
- 线程堆栈:简称栈 Stack托管堆: 简称堆 Heap使用.Net框架开发程序的时候,我们无需关心内存分配问题,因为有GC这个大管家给我们料
- 前言平时日常开发用得最多是Http通讯,接口调试也比较简单的,也有比较强大的框架支持(OkHttp)。个人平时用到socket通讯的地方是A
- 1 二叉排序树的概述本文没有介绍一些基础知识。对于常见查找算法,比如顺序查找、二分查找、插入查找、斐波那契查找还不清楚的,可以看这篇文章:常
- 本文实例讲述了C#自定义处理xml数据类。分享给大家供大家参考。具体分析如下:这个C#类专门用户处理xml数据,可以大大简化xml的操作,类
- Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。一、当两个并发线程访问同一个
- 一、内部类的概念在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。p
- 优点1.观察者和被观察者是抽象耦合的。2.建立一套触发机制。缺点1.如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知
- 一、流程和任务的关系以下是一个简单的请假流程图,其中有一个开始事件,两个用户任务,一个结束事件。启动流程后,activiti会自动创建第一个
- 显示当前运行java代码的运行时的各种参数。不带显String操作。package systeminfo;import java.util.
- JPA Specification常用查询+排序1.第一步:继承父类public interface TblCarton2RCardLogR