java - 为什么 Spring 框架中的 MethodMatcher 接口(interface)采用 targetClass 作为参数,而 Pointcut 已经定义了 Classfilter?

标签 java spring spring-aop

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 be DefaultFoo. In this case, the method may be DefaultFoo.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/

相关文章:

Java 不会使用 Apache commons exec 执行 shellscript 中的所有命令

java - Spring - 是否有可能获取所有包,并在@ComponentScan 中注册?

在其他 JAR 中定义时未执行 Spring Aspect

spring - 为什么spring不依赖aspectj会抛出aspectj错误?

java - 当手指在屏幕的同一位置时执行事件? libgdx

java - Eclipse 自动完成 : Java 1. 7 Generics Diamond

spring - 使用 Spring 启动对 mongoDB 进行身份验证失败

java - 服务层的 Spring AOP

java - Spring ReflectionTestUtils 不设置原始数据类型字段

java - hibernate 异常 : No Session found for current thread