001/* 002 * Copyright 2002-2019 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 * <p>Concrete implementations of this interface typically should provide proper 044 * implementations of {@link Object#equals(Object)} and {@link Object#hashCode()} 045 * in order to allow the matcher to be used in caching scenarios — for 046 * example, in proxies generated by CGLIB. 047 * 048 * @author Rod Johnson 049 * @since 11.11.2003 050 * @see Pointcut 051 * @see ClassFilter 052 */ 053public interface MethodMatcher { 054 055 /** 056 * Perform static checking whether the given method matches. 057 * <p>If this returns {@code false} or if the {@link #isRuntime()} 058 * method returns {@code false}, no runtime check (i.e. no 059 * {@link #matches(java.lang.reflect.Method, Class, Object[])} call) 060 * will be made. 061 * @param method the candidate method 062 * @param targetClass the target class 063 * @return whether or not this method matches statically 064 */ 065 boolean matches(Method method, Class<?> targetClass); 066 067 /** 068 * Is this MethodMatcher dynamic, that is, must a final call be made on the 069 * {@link #matches(java.lang.reflect.Method, Class, Object[])} method at 070 * runtime even if the 2-arg matches method returns {@code true}? 071 * <p>Can be invoked when an AOP proxy is created, and need not be invoked 072 * again before each method invocation, 073 * @return whether or not a runtime match via the 3-arg 074 * {@link #matches(java.lang.reflect.Method, Class, Object[])} method 075 * is required if static matching passed 076 */ 077 boolean isRuntime(); 078 079 /** 080 * Check whether there a runtime (dynamic) match for this method, 081 * which must have matched statically. 082 * <p>This method is invoked only if the 2-arg matches method returns 083 * {@code true} for the given method and target class, and if the 084 * {@link #isRuntime()} method returns {@code true}. Invoked 085 * immediately before potential running of the advice, after any 086 * advice earlier in the advice chain has run. 087 * @param method the candidate method 088 * @param targetClass the target class 089 * @param args arguments to the method 090 * @return whether there's a runtime match 091 * @see MethodMatcher#matches(Method, Class) 092 */ 093 boolean matches(Method method, Class<?> targetClass, Object... args); 094 095 096 /** 097 * Canonical instance that matches all methods. 098 */ 099 MethodMatcher TRUE = TrueMethodMatcher.INSTANCE; 100 101}