导读 | 使用版本为 Spring Framework 5.2.2.RELEASE,来探索BeanFactory和ApplicationContext的关系。 |
开始
首先创建了Repository类,有两个属性,类型为 BeanFactory 和 ApplicationContext
public class Repository { private BeanFactory beanFactory; private ApplicationContext applicationContext; public ApplicationContext getApplicationContext() { return applicationContext; } public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } public BeanFactory getBeanFactory() { return beanFactory; } public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } }
创建配置bean的xml
<beans xmlns="//www.springframework.org/schema/beans" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="//www.springframework.org/schema/beans //www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="repository" class="ioc.overview.repository.Repository" autowire="byType"></bean> </beans>
创建测试类:
public class DependencyInjectionDemo { public static void main(String[] args) { BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/injection-context.xml"); Repository repository = beanFactory.getBean("userRepository", Repository.class); System.out.println("injected beanFactory == main beanFactory: " + (repository.getBeanFactory() == beanFactory)); System.out.println("injected applicationContext == main beanFactory: " + (repository.getApplicationContext() == beanFactory)); } }
打印如下:
injected beanFactory == main beanFactory: false injected applicationContext == main beanFactory: true
为什么 beanFactory 不等于 beanFactory 呢?
看看类的继承关系
ClassPathXmlApplicationContext继承自 AbstractApplicationContext 。
// AbstractApplicationContext 实现了 ApplicationContext 接口 public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { } public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable { } // ApplicationContext 是 BeanFactory的子接口 public interface ApplicationContext extends ListableBeanFactory... public interface ListableBeanFactory extends BeanFactory {}
再来看 ConfigurableApplicationContext 中,声明了一个获取 beanFactory 的方法:
ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
自己就是 beanFactory,为什么还要声明这个方法呢?
接着,来看这个方法的实现:
AbstractRefreshableApplicationContext#getBeanFactory
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext { /** Bean factory for this context. */ @Nullable private DefaultListableBeanFactory beanFactory; @Override public final ConfigurableListableBeanFactory getBeanFactory() { synchronized (this.beanFactoryMonitor) { if (this.beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext"); } return this.beanFactory; } }
再来看看 getBean 的实现,他使用了组合的方式,使用 beanFactory 对象进行获取 bean。
@Override publicT getBean(String name, Class requiredType) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name, requiredType); }
总结
BeanFactory 是底层的Ioc容器,ApplicationContext 继承了它,并增加了一些特性。在实现方面,ApplicationContext 组合了一个 BeanFactory 的实现,使用这个实现对象来完成一些操作。
原文来自:
本文地址://q13zd.cn/beanfactory-applicationcontext.html编辑:薛鹏旭,审核员:逄增宝
Linux大全:
Linux系统大全: