代码之家  ›  专栏  ›  技术社区  ›  Koray Tugay

为什么Spring框架中的MethodMatcher接口将targetClass作为参数,而切入点已经定义了类过滤器?

  •  0
  • Koray Tugay  · 技术社区  · 7 年前

    这个 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 接口已经声明,其唯一目的是确定类是否可以通过过滤器:

    /**
     * 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 接口是否再次检查课程资格?为什么这个接口的方法有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;
    
    } 
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Indra Basak    7 年前

    这个 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

    给定一个方法(可能来自接口)和使用的目标类 在当前的AOP调用中,如果有对应的目标方法,请找到相应的目标方法。E、 g.该方法可以是 IFoo.bar() 目标类可能是 DefaultFoo DefaultFoo.bar() . 这样可以找到该方法上的属性。

    注: 与…对比 org.springframework.util.ClassUtils#getMostSpecificMethod ,该方法解析Java 5桥接方法,以便从 起初的 方法定义。