转载

从源码角度来看BeanFactory和ApplicationContext的关系

大家好,我是小黑,这是年前的最后一篇推文,提前祝大家新年快乐~~

这次我们从源码角度来聊聊 BeanFactoryApplicationContext 的关系,讲一些网上文章不曾提到的点。

官方描述

先来看一下官方文档中关于 BeanFactoryApplicationContext 的描述。

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory . It adds:

WebApplicationContext

https://docs.spring.io/spring...

从官方文档可以了解到:

BeanFactory 接口提供了能够管理任何类型对象的高级配置机制。

ApplicationContextBeanFactory 的子接口,它增加了如下一些功能:

WebApplicationContext

源码简析

以下源码基于 Spring 5.0.13 版本。

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
        MessageSource, ApplicationEventPublisher, ResourcePatternResolver
public interface ListableBeanFactory extends BeanFactory

从源码可以证实到, ApplicationContext 继承了 BeanFactory

@Configurable
public class Main {

    @Autowired
    BeanFactory beanFactory;

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Main.class);
        Main bean = context.getBean(Main.class);
        // false
        System.out.println(context == bean.beanFactory);
        context.close();
    }
}

AnnotationConfigApplicationContextApplicationContext 的一个实现类,换而言之, AnnotationConfigApplicationContext 也是 BeanFactory 的一个实现类。

但是,运行上述代码, System.out.println(context == bean.beanFactory); 的输出结果为 false

这是不是意味着,在容器中, ApplicationContextBeanFactory 是两个不同的实例对象呢?

BeanFactory 和 ApplicationContext

AnnotationConfigApplicationContext 中有一个 getBeanFactory 方法。

准确来说,是 org.springframework.context.support.AbstractApplicationContext#getBeanFactory

@Configurable
public class Main {

    @Autowired
    BeanFactory beanFactory;

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Main.class);
        Main bean = context.getBean(Main.class);
        // false
        System.out.println(context == bean.beanFactory);
        // true
        System.out.println(context.getBeanFactory() == bean.beanFactory);
        context.close();
    }
}

AbstractApplicationContextApplicationContext 的抽象实现。

AnnotationConfigApplicationContext 继承了 GenericApplicationContext ,而 GenericApplicationContext 又继承了 AbstractApplicationContext

从源码角度来看BeanFactory和ApplicationContext的关系

AbstractApplicationContext 中,所有 BeanFactory 接口的实现,都是委托给了 BeanFactory 对象。

// AbstractApplicationContext#getBean(java.lang.Class<T>, java.lang.Object...)
public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
  assertBeanFactoryActive();
  return getBeanFactory().getBean(requiredType, args);
}
// AbstractApplicationContext#getBeanFactory
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

getBeanFactory() 是一个抽象方法用。

GenericApplicationContext 实现了该抽象方法:

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

    private final DefaultListableBeanFactory beanFactory;
    ...
    public final ConfigurableListableBeanFactory getBeanFactory() {
        return this.beanFactory;
    }
     ...
}

总结

ApplicationContextBeanFactory 的子接口,但是 ApplicationContext 的实例对象和 BeanFactory 的实例对象并不是同一个。

ApplicationContext 的实现中,有一个成员变量 DefaultListableBeanFactory beanFactory ,所有和 BeanFactory 接口相关的功能都是委派给这个成员变量来实现的。

ApplicationContext 实现类中的 beanFactory 成员变量和容器中的 BeanFactory 才是同一个实例对象。

原文  https://segmentfault.com/a/1190000021578159
正文到此结束
Loading...