阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

BeanFactory和ApplicationContext的关系

73次阅读
没有评论

共计 3032 个字符,预计需要花费 8 分钟才能阅读完成。

导读 使用版本为 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="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://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 呢?

看看类的继承关系
BeanFactory 和 ApplicationContext 的关系

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
	public  T getBean(String name, Class requiredType) throws BeansException {assertBeanFactoryActive();
		return getBeanFactory().getBean(name, requiredType);
	}
总结

BeanFactory 是底层的 Ioc 容器,ApplicationContext 继承了它,并增加了一些特性。在实现方面,ApplicationContext 组合了一个 BeanFactory 的实现,使用这个实现对象来完成一些操作。

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-25发表,共计3032字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中