Pointcut界面位于 Spring Framework由2个方法组成:
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;
}
ClassFilter接口(interface)已经声明了,它的唯一目的是决定一个类是否可以通过过滤器:
/**
* 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}.
*
* @author Rod Johnson
* @see Pointcut
* @see MethodMatcher
*/
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;
}
我不明白的是,为什么 MethodMatcher 中的方法会这样? 界面再次检查类(class)资格?为什么这个接口(interface)的方法有 targetClass 参数?
public interface MethodMatcher {
/**
* Perform static checking whether the given method matches. 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 (may be {@code null}, in which case
* the candidate class must be taken to be the method's declaring class)
* @return whether or not this method matches statically
*/
boolean matches(Method method, Class<?> targetClass);
/**
* 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 (may be {@code null}, in which case
* the candidate class must be taken to be the method's declaring 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;
}
最佳答案
targetClass
MethodMatcher.matches(Method method, Class<?> targetClass)
中指定不用于检查目标调用类的资格。
它用于查找最具体的目标方法,该方法适用于给定方法(指定为参数)的目标类。它还解决了 Java bridge methods 的问题.
这是一个示例 matches
方法来自org.springframework.aop.aspectj.AspectJExpressionPointcut
类。
public boolean matches(Method method, Class<?> targetClass, boolean beanHasIntroductions) {
this.checkReadyToMatch();
Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
ShadowMatch shadowMatch = this.getShadowMatch(targetMethod, method);
...
}
这是来自 org.springframework.aop.support.AopUtils#getMostSpecificMethod 的 Javadoc
Given a method, which may come from an interface, and a target class used in the current AOP invocation, find the corresponding target method if there is one. E.g. the method may be
IFoo.bar()
and the target class may beDefaultFoo
. In this case, the method may beDefaultFoo.bar()
. This enables attributes on that method to be found.NOTE: In contrast to
org.springframework.util.ClassUtils#getMostSpecificMethod
, this method resolves Java 5 bridge methods in order to retrieve attributes from the original method definition.
关于java - 为什么 Spring 框架中的 MethodMatcher 接口(interface)采用 targetClass 作为参数,而 Pointcut 已经定义了 Classfilter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47421629/