Spring源码:IOC容器BeanFactory和ApplicationContext体系结构

BeanFactory接口设计

在这里插入图片描述

  1. BeanFactory
    顶层接口,主要提供getBean方法,从BeanFactory获取给定beanName以及对应的bean对象实例

  2. ListableBeanFactory
    主要提供根据给定条件,如type,Annotation,获取对应的所有beans列表的接口

  3. HierarchicalBeanFactory
    提供getParentBeanFactory方法,使beanFactory具备层次化

  4. ConfigurableBeanFactory
    继承HierarchicalBeanFactory, SingletonBeanRegistry, 主要提供对BeanFactory进行相关配置的接口,如类加载器classLoader,beanPostProcessor,类型转换器,属性编辑器等在加载、创建和初始化bean实例时,需要用到的一些功能组件

  5. AbstractBeanFactory

继承FactoryBeanRegistrySupport,实现ConfigurableBeanFactory接口,抽象类,主要实现的接口方法如getBean、doGetBean、destroyBean、addBeanPostProcessor等。其中抽象类DefaultSingletonBeanRegistry继承DefaultSingletonBeanRegistry接口,其中factoryBeanObjectCache用于保存FactoryBean创建的bean实例
在这里插入图片描述

  1. AutowireCapableBeanFactory
    主要提供对于BeanFactory创建的bean,使用autowire的方式对其所依赖的beans进行依赖注入 提供createBean、autowireBean、configureBean等

  2. AbstractAutowireCapableBeanFactory
    继承AbstractBeanFactory ,实现 AutowireCapableBeanFactory。 常用方法 createBean、doCreateBean

  3. 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。

  1. 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值