一、上代码抛问题
UserReository.java
public class UserReository {
private Collection<User> users; // 自定义 Bean
private BeanFactory beanFactory; // 内建非 Bean 对象(依赖)
private ObjectFactory<User> objectFactoryUser;
private ObjectFactory<ApplicationContext> objectFactoryContext;
.... setter / getter ...
@Override
public String toString() {
return "UserReository{" +
"users=" + users +
", beanFactory=" + beanFactory +
", objectFactoryUser=" + objectFactoryUser +
", objectFactoryContext=" + objectFactoryContext +
'}';
}
}
dependency-injection-context.xml
<!-- autowire自动注入 -->
<bean id="userReository2" class="org.geekbang.thinking.in.spring.ioc.overview.repository.UserReository" autowire="byType"/>
测试实验:
public static void test06(){
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");
UserReository userReository = beanFactory.getBean("userReository2", UserReository.class);
// 思考,为什么不相等
System.out.println(beanFactory == userReository.getBeanFactory());
System.out.println(beanFactory);
System.out.println(userReository.getBeanFactory());
}
打印结果:
false
org.springframework.context.support.ClassPathXmlApplicationContext@6aaceffd, started on Thu Mar 25 23:52:39 CST 2021
org.springframework.beans.factory.support.DefaultListableBeanFactory@313b2ea6: defining beans [user,superUser,objectFactory,userReository,userReository2]; root of factory hierarchy
二、ClassPathXmlApplicationContext 类的层级结构
// -> 表示实现的接口
ClassPathXmlApplicationContext
AbstractXmlApplicationContext
AbstractRefreshableConfigApplicationContext
AbstractRefreshableApplicationContext
-> BeanNameAware
-> InitializingBean
AbstractRefreshableApplicationContext
AbstractApplicationContext
DefaultResourceLoader
-> ConfigurableApplicationContext
ApplicationContext
BeanFactory
从继承关系来看,ClassPathXmlApplicationContext 继承自 AbstractRefreshableApplicationContext,而在 AbstractRefreshableApplicationContext中
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
@Nullable
private Boolean allowBeanDefinitionOverriding;
@Nullable
private Boolean allowCircularReferences;
/** Bean factory for this context. */
@Nullable
private volatile DefaultListableBeanFactory beanFactory; // 以组合的方式将beanFactory注入进来
....
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
DefaultListableBeanFactory beanFactory = this.beanFactory;
if (beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return beanFactory;
}
}
三、再看 getBean 方法
org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.Class)
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
清楚这一点,我们就知道,ApplicationContext 跟 BeanFactory 是两个东西。
虽然可以直接赋值,那是因为ApplicationContext继承了BeanFactory,但是实际使用的时候,ApplicationContext是将BeanFactory集成进来的,这样 ApplicationContext 中就会包含所有 BeanFactory 的功能,所有 BeanFactory 的功能都是交由组合的 DefaultListableBeanFactory 实现
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");
四、总结
BeanFactory 是底层的Bean容器,虽然 ApplicationContext 是BeanFactory的子类,但是实际应用中ApplicationContext 只是将 BeanFactory 容器集成进来了,然后做了一些扩展性的功能