小马哥课程笔记
BeanFactory 和 ApplicationContext 谁才是 Spring IoC 容器?
这个表达式为什么不会成立
userRepository.getBeanFactory() == beanFactory is false
这是因为 ApplicationContext is BeanFactory
public class DependencyInjectionDemo {
public static void main ( String [ ] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext ( "classpath:/META-INF/dependency-injection-context.xml" ) ;
UserRepository userRepository = applicationContext. getBean ( "userRepository" , UserRepository . class ) ;
System . out. println ( userRepository. getBeanFactory ( ) ) ;
ObjectFactory userFactory = userRepository. getObjectFactory ( ) ;
System . out. println ( userFactory. getObject ( ) == applicationContext) ;
Environment environment = applicationContext. getBean ( Environment . class ) ;
System . out. println ( "获取 Environment 类型的 Bean:" + environment) ;
}
private static void whoIsIoCContainer ( UserRepository userRepository, ApplicationContext applicationContext) {
System . out. println ( userRepository. getBeanFactory ( ) == applicationContext) ;
}
}
来自于官网的对于BeanFactory和ApplicationContext的阐述
ApplicationContext is sub-interface of BeanFactory
一种设计模式
代码中new ClassPathXmlApplicationContext() 得到的是 ClassPathXmlApplicationContext 在ClassPathXmlApplicationContext 向上查看继承关系 它实现了ConfigurableApplicationContext 这是一个可配置的接口 ConfigurableApplicationContext 又继承了 ApplicationContext ApplicationContext 又继承了 BeanFactory 所以ConfigurableApplicationContext 它本身就是一个 BeanFactory 但是它本身还是提供了一个 ConfigurableListableBeanFactory getBeanFactory() 的方法; 而且它还有一个void setParent(@Nullable ApplicationContext parent)方法 然后查看getBeanFactory的AbstractRefreshableApplicationContext实现类中的getBeanFactory方法
@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;
}
}
可以发现beanFactory 这里是一个组合,AbstractRefreshableApplicationContext是把DefaultListableBeanFactory 组合进来了而不是通过继承,这里有点类似代理模式. 这里也是userRepository.getBeanFactory() == beanFactory is false的原因,他们毕竟是两个对象(BeanFactory 和 DefaultListableBeanFactory ). 然后再来看getBean的实现,相当于就是利用了DefaultListableBeanFactory 代理的BeanFactory去获得Bean
@Override
public < T > T getBean ( Class < T > requiredType) throws BeansException {
assertBeanFactoryActive ( ) ;
return getBeanFactory ( ) . getBean ( requiredType) ;
}
最后可以得出一个结论,BeanFactory是一个底层的IoC容器,ApplicationContext 是在这基础上增加了一些特性,并且ApplicationContext 是BeanFactory完整的超集,BeanFactory拥有的ApplicationContext 也全都拥有