BeanFactory接口设计
-
BeanFactory
顶层接口,主要提供getBean方法,从BeanFactory获取给定beanName以及对应的bean对象实例 -
ListableBeanFactory
主要提供根据给定条件,如type,Annotation,获取对应的所有beans列表的接口 -
HierarchicalBeanFactory
提供getParentBeanFactory方法,使beanFactory具备层次化 -
ConfigurableBeanFactory
继承HierarchicalBeanFactory, SingletonBeanRegistry, 主要提供对BeanFactory进行相关配置的接口,如类加载器classLoader,beanPostProcessor,类型转换器,属性编辑器等在加载、创建和初始化bean实例时,需要用到的一些功能组件 -
AbstractBeanFactory
继承FactoryBeanRegistrySupport,实现ConfigurableBeanFactory接口,抽象类,主要实现的接口方法如getBean、doGetBean、destroyBean、addBeanPostProcessor等。其中抽象类DefaultSingletonBeanRegistry继承DefaultSingletonBeanRegistry接口,其中factoryBeanObjectCache用于保存FactoryBean创建的bean实例
-
AutowireCapableBeanFactory
主要提供对于BeanFactory创建的bean,使用autowire的方式对其所依赖的beans进行依赖注入 提供createBean、autowireBean、configureBean等 -
AbstractAutowireCapableBeanFactory
继承AbstractBeanFactory ,实现 AutowireCapableBeanFactory。 常用方法 createBean、doCreateBean -
DefaultListableBeanFactory
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
...
}
BeanFactory接口体系的默认实现类,实现以上接口的功能,其中getBean方法主要通过内部私有方法resolveBean来调用BeanProvider.getObject来获取bean实例。提供BeanDefinition的存储map,Bean对象对象的存储map。
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
其中Bean对象实例的存储map,定义在FactoryBeanRegistrySupport,FactoryBeanRegistrySupport实现了SingletonBeanRegistry接口,而DefaultListableBeanFactory的基类AbstractBeanFactory,继承于FactoryBeanRegistrySupport。
- StaticListableBeanFactory
实现ListableBeanFactory 简单实现 不支持动态注册
以上BeanFactory接口层次主要是以Bean的获取为主的设计。而注册是在BeanDefinitionRegistr和SingletonBeanRegistry中设计的。
ApplicationContext上下文体系
Spring容器通常指的是ApplicationContext的体系结构设计,即整个Spring框架的IOC功能,是通过ApplicationContext接口实现类来提供给应用程序使用的。应用程序通过ApplicationContext提供方法来间接与内部Bean工厂交互,如获取Bean对象实例等。
在Spring框架内部设计当中,ApplicationContext是Spring容器所管理、维护的beans对象的一个运行环境,即ApplicationContext包含一些功能组件:保存外部属性文件(properties文件,yml文件等)的属性键值对集合的Environment,容器配置的位置contextConfigLocation等等,用于创建bean对象需要的一些外部依赖;
而ApplicationContext内部最重要的组件,就是BeanFactory体系结构,ApplicationContext通过BeanFactory来维护Spring容器所管理的类对应的BeanDefintions,通过BeanFactory来获取类对象bean。与BeanFactory配套的就是ApplicationContext维护多个BeanFactoryPostProcessor,BeanPostProcessor来对BeanFactory进行拓展,对BeanFactory自身或所创建的bean对象实例进行加工、功能拓展,实现整体设计的高拓展性。
-
ApplicationContext
context顶层接口,提供bean容器的一个运行环境,而实际的bean容器为内部绑定的BeanFactory
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver
- ConfigurableApplicationContext
提供与applicationListener,environment,beanFactoryProcessor等相关的get/set方法,还有启动入口方法refresh。 - AbstractApplicationContext
抽象类,提供ConfigurableApplicationContext接口的refresh方法的模板实现,容器启动的骨架实现,
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
- AbstractRefreshableApplicationContext
供多次调用refresh 刷新容器。 先调用destroyBeans()、closeBeanFactory(),然后再创建一个新的bean工厂createBeanFactory并重新加载beanDefinitions - AbstractRefreshableConfigApplicationContext
定义数组类型的configLocations成员变量,以及set/get方法,用于保存xml配置文件存放的地址。故可以在外部定义多个xml文件来配置需要注册的bean。 - AbstractXmlApplicationContext
继承于AbstractRefreshableConfigApplicationContext,指定使用xml文件保存配置。
ClassPathXmlApplicationContext:具体实现类,继承于AbstractXmlApplicationContext抽象类,指定从类路径下加载xml配置文件。
FileSystemXmlApplicationContext:具体实现类,继承于AbstractXmlApplicationContext,指定从文件系统加载xml配置文件。 - GenericApplicationContext
通用类 extends AbstractApplicationContext implements BeanDefinitionRegistry。 通过实现BeanDefinitionRegistry接口来提供往内部的beanFactory注入beanDefinitions,而beanDefinitions的来源则是通过BeanDefinitionParser解析,如xml文件来获取的。不支持重复调用refresh。
GenericApplicationContext genericApplicationContext = new GenericApplicationContext();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(genericApplicationContext);
int count = xmlBeanDefinitionReader.loadBeanDefinitions(new ClassPathResource("spring/testApplicationContext.xml"));
System.out.println("loadBean count:" + count);
genericApplicationContext.refresh();
Iterator<String> beanNamesIterator = genericApplicationContext.getBeanFactory().getBeanNamesIterator();
while (beanNamesIterator.hasNext()) {
String beanName = beanNamesIterator.next();
System.out.println(beanName);
Object bean = genericApplicationContext.getBean(beanName);
}
genericApplicationContext.close();
- GenericXmlApplicationContext
比ClassPathXmlApplicationContext,FileSystemXmlApplicationContext更加通用的基于xml配置文件的ApplicationContext。即可以在构造函数中指定配置数来源,使用的Resource类型的数组参数。而前两者都是使用String类型的configLocations数组,即路径数组。 - AnnotationConfigApplicationContext
extends GenericApplicationContext implements AnnotationConfigRegistry 处理我们项目中使用的注解的类,即将@Controller,@Component等注解的类注册成bean。继承于GenericApplicationContext,并实现AnnotationConfigRegistry接口(AnnotationConfigRegistry接口主要实现将给定的beanDefinition注册到绑定的beanFactory中–register和scan方法)。处理basePackages的包下面的@Component,以及派生的如@Service,@Controller,@Repository等,具体可以通过includeFilters和excludeFilters来配置需要哪些注解的类和排除哪些注解的类
register和scan方法主要依赖AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
this.scanner.scan(basePackages);
}
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(MyConfig.class);
context.refresh();
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
context.close();
参考文章:
https://xieyizun.blog.csdn.net/article/details/86597964
https://xieyizun.blog.csdn.net/article/details/86666827