001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.aop; 018 019import java.lang.reflect.Method; 020 021/** 022 * Part of a {@link Pointcut}: Checks whether the target method is eligible for advice. 023 * 024 * <p>A MethodMatcher may be evaluated <b>statically</b> or at <b>runtime</b> (dynamically). 025 * Static matching involves method and (possibly) method attributes. Dynamic matching 026 * also makes arguments for a particular call available, and any effects of running 027 * previous advice applying to the joinpoint. 028 * 029 * <p>If an implementation returns {@code false} from its {@link #isRuntime()} 030 * method, evaluation can be performed statically, and the result will be the same 031 * for all invocations of this method, whatever their arguments. This means that 032 * if the {@link #isRuntime()} method returns {@code false}, the 3-arg 033 * {@link #matches(java.lang.reflect.Method, Class, Object[])} method will never be invoked. 034 * 035 * <p>If an implementation returns {@code true} from its 2-arg 036 * {@link #matches(java.lang.reflect.Method, Class)} method and its {@link #isRuntime()} method 037 * returns {@code true}, the 3-arg {@link #matches(java.lang.reflect.Method, Class, Object[])} 038 * method will be invoked <i>immediately before each potential execution of the related advice</i>, 039 * to decide whether the advice should run. All previous advice, such as earlier interceptors 040 * in an interceptor chain, will have run, so any state changes they have produced in 041 * parameters or ThreadLocal state will be available at the time of evaluation. 042 * 043 * @author Rod Johnson 044 * @since 11.11.2003 045 * @see Pointcut 046 * @see ClassFilter 047 */ 048public interface MethodMatcher { 049 050 /** 051 * Perform static checking whether the given method matches. 052 * <p>If this returns {@code false} or if the {@link #isRuntime()} 053 * method returns {@code false}, no runtime check (i.e. no 054 * {@link #matches(java.lang.reflect.Method, Class, Object[])} call) 055 * will be made. 056 * @param method the candidate method 057 * @param targetClass the target class (may be {@code null}, in which case 058 * the candidate class must be taken to be the method's declaring class) 059 * @return whether or not this method matches statically 060 */ 061 boolean matches(Method method, Class<?> targetClass); 062 063 /** 064 * Is this MethodMatcher dynamic, that is, must a final call be made on the 065 * {@link #matches(java.lang.reflect.Method, Class, Object[])} method at 066 * runtime even if the 2-arg matches method returns {@code true}? 067 * <p>Can be invoked when an AOP proxy is created, and need not be invoked 068 * again before each method invocation, 069 * @return whether or not a runtime match via the 3-arg 070 * {@link #matches(java.lang.reflect.Method, Class, Object[])} method 071 * is required if static matching passed 072 */ 073 boolean isRuntime(); 074 075 /** 076 * Check whether there a runtime (dynamic) match for this method, 077 * which must have matched statically. 078 * <p>This method is invoked only if the 2-arg matches method returns 079 * {@code true} for the given method and target class, and if the 080 * {@link #isRuntime()} method returns {@code true}. Invoked 081 * immediately before potential running of the advice, after any 082 * advice earlier in the advice chain has run. 083 * @param method the candidate method 084 * @param targetClass the target class (may be {@code null}, in which case 085 * the candidate class must be taken to be the method's declaring class) 086 * @param args arguments to the method 087 * @return whether there's a runtime match 088 * @see MethodMatcher#matches(Method, Class) 089 */ 090 boolean matches(Method method, Class<?> targetClass, Object... args); 091 092 093 /** 094 * Canonical instance that matches all methods. 095 */ 096 MethodMatcher TRUE = TrueMethodMatcher.INSTANCE; 097 098}