今天在查看spring源码时在AbstractApplicationContext类中看到了如下代码
跟进 refreshBeanFactory()方法后发现是一个抽象方法,如下:
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
而正在实现方法的是她的子类
如是陷入了深深的纳闷中“父类竟然能直接调用子类中的方法?”
经过网上搜索发现这叫委派模式。
网上是这么介绍的:
比较有用的例子如下:
***在这个例子里,类C可以委托类A或类B,类C拥有方法使自己可以在类A或类B间选择。因为类A或类B必须实现接口I规定的方法,所以在这里委托是类型安全的。**/
package Paint;
interface I {
void f();
void g();
}
class A implements I {
public void f() {
System.out.println("A: doing f()");
}
public void g() {
System.out.println("A: doing g()");
}
}
class B implements I {
public void f() {
System.out.println("B: doing f()");
}
public void g() {
System.out.println("B: doing g()");
}
}
class C implements I {
I i = new A();
public void f() {
i.f();
}
public void g() {
i.g();
}
public void toA() {
i = new A();
}
public void toB() {
i = new B();
}
}
public class Main {
public static void main(String[] args) {
C c = new C();
c.f(); // output: A: doing f()
c.g(); // output: A: doing g()
c.toB(); // 更换委托对象
c.f(); // output: B: doing f()
c.g(); // output: B: doing g()
}
}
经过分析总结大体为“多个子类实现父类的方法,其中一个子类在实现父类方法时根据情况调用其他子类的方法”
回到我们最开始的疑问上来“会不会是AbstractApplicationContext类的子类或者孙子类调用了obtainFreshBeanFactory方法?“
跟踪方法的调用路径如下:
最开始发起调用的类是: FileSystemXmlApplicationContext
查看类的类图如下:
发现原来 FileSystemXmlApplicationContext是AbstractApplicationContext的第四代子孙,通过方法的继承传递,最终调用了
AbstractRefreshableConfigApplicationContext的refreshBeanFactory()方法,终于真相大白。