这篇文章,我们来谈一谈Spring中的属性注入 (3)

上面的代码整体来说应该很简单,就如我们之前所说的,处理带有@Autowired注解的字段及方法,同时会过滤掉所有的静态字段及方法。上面复杂的地方在于对桥接方法的处理,可能大部分人都没办法理解这几行代码:

// 第一行 Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); // 第二行 if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { return; } // 第三行 if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { }

要理解这些代码,首先你得知道什么是桥接,为此我已经写好了一篇文章:

Spring杂谈 | 从桥接方法到JVM方法调用

除了在上面的文章中提到的桥接方法外,还有一种特殊的情况

// A类跟B类在同一个包下,A不是public的 class A { public void test(){ } } // 在B中会生成一个跟A中的方法描述符(参数+返回值)一模一样的桥接方法 // 这个桥接方法实际上就是调用父类中的方法 // 具体可以参考:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=63424113 public class B extends A { }

在理解了什么是桥接之后,那么上边的第一行代码你应该就能看懂了,就以上面的代码为例,B中会生成一个桥接方法,对应的被桥接的方法就是A中的test方法。

接着,我们看看第二行代码

public static boolean isVisibilityBridgeMethodPair(Method bridgeMethod, Method bridgedMethod) { // 说明这个方法本身就不是桥接方法,直接返回true if (bridgeMethod == bridgedMethod) { return true; } // 说明是桥接方法,并且方法描述符一致 // 当且仅当是上面例子中描述的这种桥接的时候这个判断才会满足 // 正常来说桥接方法跟被桥接方法的返回值+参数类型肯定不一致 // 所以这个判断会过滤掉其余的所有类型的桥接方法 // 只会保留本文提及这种特殊情况下产生的桥接方法 return (bridgeMethod.getReturnType().equals(bridgedMethod.getReturnType()) && Arrays.equals(bridgeMethod.getParameterTypes(), bridgedMethod.getParameterTypes())); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsspw.html