赞
踩
IoC只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是在类内部主动创建依赖对象,从而导致类与类之间高耦合;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。
Spring Framework对控制反转(IoC)原理的实现。IoC也称为依赖注入(DI)。这是一个过程,通过这个过程,对象只能通过构造函数参数,工厂方法的参数或在构造或从工厂方法返回后在对象实例上设置的属性来定义它们的依赖关系(即,它们使用的其他对象)。 然后容器在创建bean时注入这些依赖项。此过程基本上是bean本身的逆(因此名称,控制反转),通过使用类的直接构造或诸如服务定位器模式的机制来控制其依赖关系的实例化或位置。(官方文档5.x说明)
在spring中,对象和对象依赖关系怎么表示?
- 初始化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为连Autowired注解都是没有解析的;
- 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了;
- 如果Bean实现了BeanNameAware接口,则调用setBeanName方法;
- 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;
- 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;
- 调用BeanPostProcessor的postProcessBeforeInitialization方法;
- 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法;
- 如果Bean定义了init-method方法,则调用Bean的init-method方法;
- 调用BeanPostProcessor的postProcessAfterInitialization方法;当进行到这一步,Bean已经被准备就绪了,一直停留在应用的上下文中,直到被销毁;
- 如果应用的上下文被销毁了,如果Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method声明了销毁方法也会被调用。
Spring Bean的创建是典型的工厂模式,这一系列的Bean工厂,也即IOC容器为开发者管理对象间的依赖关系提供了很多便利和基础服务,在Spring中有许多的IOC容器的实现供用户选择和使用,其相互关系如下:
其中BeanFactory作为最顶层的一个接口类,它定义了IOC容器的基本功能规范,即定义获取bean和bean的各种属性。BeanFactory 有三个子类:ListableBeanFactory、HierarchicalBeanFactory 和AutowireCapableBeanFactory。但是从上图中我们可以发现最终的默认实现类是 DefaultListableBeanFactory,他实现了所有的接口。那为何要定义这么多层次的接口呢?查阅这些接口的源码和说明发现,每个接口都有他使用的场合,它主要是为了区分 Spring 内部在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制。例如 ListableBeanFactory 接口表示这些 Bean 是可列表的,而 HierarchicalBeanFactory 表示的是在应用中可以起多个 BeanFactory,然后可以将各个 BeanFactory 设置为父子关系。AutowireCapableBeanFactory 接口定义 Bean 的自动装配规则。这四个接口共同定义了 Bean 的集合、Bean 之间的关系、以及 Bean 行为。
在BeanFactory里只对IOC容器的基本行为作了定义,根本不关心你的bean是如何定义怎样加载的。正如我们只关心工厂里得到什么的产品对象,至于工厂是怎么生产这些对象的,这个基本的接口不关心。
而要知道工厂是如何产生对象的,我们需要看具体的IOC容器实现,spring提供了许多IOC容器的实现。比如XmlBeanFactory,ClasspathXmlApplicationContext等。其中XmlBeanFactory就是针对最基本的ioc容器的实现,这个IOC容器可以读取XML文件定义的BeanDefinition(XML文件中对bean的描述),如果说XmlBeanFactory是容器中的屌丝,ApplicationContext应该算容器中的高帅富.
IoC容器的初始化包括BeanDefinition的Resource定位、载入和注册这三个基本的过程。ApplicationContext是Spring提供的一个高级的IoC容器, 它除了能够提供IoC容器的基本功能外,还为用户提供了以下的附加服务:
1. 支持信息源,可以实现国际化(实现MessageSource接口)
2. 访问资源(实现ResourcePatternResolver接口)
3. 支持应用事件(实现ApplicationEventPublisher接口)
SpringIOC容器管理了我们定义的各种Bean对象及其相互的关系,Bean对象在Spring实现中是以BeanDefinition来描述的,其继承体系如下:
Bean 的解析过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证有足够的灵活性,以应对可能的变化。Bean 的解析主要就是对 Spring 配置文件的解析。这个解析过程主要通过下图中的类完成:
后文将以xml文件加载的方式阐述容器的整个启动过程,先看下最启动 Spring 容器的代码:
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
- }
第一步,我们肯定要从 ClassPathXmlApplicationContext 的构造方法说起。
- public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {
- super(parent);
- //根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割)
- setConfigLocations(configLocations);
- if (refresh) {
- //核心方法
- refresh();
- }
- }
ClsassPathXmlApplicationContext支持多个配置文件以数组方式同时传入
- public void setConfigLocations(@Nullable String... locations) {
- if (locations != null) {
- Assert.noNullElements(locations, "Config locations must not be null");
- this.configLocations = new String[locations.length];
- for (int i = 0; i < locations.length; i++) {
- this.configLocations[i] = resolvePath(locations[i]).trim();
- }
- }
- else {
- this.configLocations = null;
- }
- }
设置了路径之后,便可以根据路径做配置文件的解析以及各种功能的实现了,可以说Refresh()中包含了几乎 ApplicationContext中提供的全部功能,而且此函数中逻辑非常清晰明了。
- //AbstractApplicationContext 515行
- public void refresh() throws BeansException, IllegalStateException {
- //ApplicationContext 建立起来以后,是可以通过调用 refresh() 这个方法重建的,需要锁保证操作原子性
- synchronized (this.startupShutdownMonitor) {
- //准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
- prepareRefresh();
-
- // 这步比较关键,这步完成后,xml配置文件就会解析成BeanDefinition定义,注册到 BeanFactory中,
- // 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
- // 注册也只是将这些信息都保存到了注册中心(核心是一个 beanName-> beanDefinition 的 map)
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
-
- //对BeanFactory进行各种功能填充,如设置BeanFactory的类加载器,添加 BeanPostProcessor,注册特殊的BeanAware
- prepareBeanFactory(beanFactory);
-
- try {
- //这里是提供给子类覆盖做扩展处理,比如具体的子类可以在这步的时候添加BeanFactoryPostProcessor的实现类或做点什么事
- postProcessBeanFactory(beanFactory);
-
- //调用BeanFactoryPostProcessor各个实现类的postProcessBeanFactory() 方法
- invokeBeanFactoryPostProcessors(beanFactory);
-
- //注册BeanPostProcessor的实现类,注意看和BeanFactoryPostProcessor的区别
- //这里只是注册,真正的调用是在getBean(),即真正实例化的时候
- registerBeanPostProcessors(beanFactory);
-
- //为上下文初始化Message源,即不同语言的消息体, 国际化处理
- initMessageSource();
-
- //初始化当前 ApplicationContext 的事件广播器
- initApplicationEventMulticaster();
-
- //典型的模板方法(钩子方法),
- //留给子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
- onRefresh();
-
- //在所有注册的bean中查找Listenerbean注册到消息广播报器中
- registerListeners();
-
- // 重点
- // 初始化所有的singletonBeans(lazy-init的除外)
- finishBeanFactoryInitialization(beanFactory);
-
- //最后,广播事件,ApplicationContext 初始化完成
- 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();
- }
- }
- }
下面概括一下refresh()初始化的步骤,并从中解释一下它为我们供的功能
1. 初始化前的准备工作,例如对系统属性或者环境变量进行准备及验证。在某种情况下项目的使用需要读取某些系统变量,而这个变量的设置很可能会影响着系统的正确性,那么 classPathXmlApplicationContext 为我们提供的这个准备函数就显得非常必要,它可以在 Spring 启动的时候提前对必须的变量进行存在性验证。
2. 初始化BeanFactory并进行 XML文件读取
之前有提到classPathXmlApplicationContext 包含 BeanFacto ry 所提供的一切特征,那么在这一步骤中将会复用 BeanFactory 中的配置文件读取解析及其他功能,这一步之后,ClassPathXmlApplicationContext 实际上就已包含了beanFactory 所提供的功能,也就是可以进行 bean 的提取等基础操作了。
3. BeanFactory 进行各种功能填充
@Qualifier @Autowired 应该是大家非常熟悉的注解 ,那么这两个注解正是在这个步骤中增加的支持
4. 子类覆盖postProcessBeanFactory(beanFactory)方法做额外的处理
Spring 之所以强大,为世人所推崇,除了它功能上为大家提供了便利外,还有一方面是它的完美架构,开放式的架构让使用它的程序员很容易根据业务需要扩展已经存在的功能,这种开放式的设计在Spring中随处可见,例如在本例中就提供了一个空的函数实现 postProcessBeanFactory 来方便程序员在业务上做进一步扩展。
5. 激活各种 BeanFactory 处理器
6. 注册拦截 bean 创建的 bean 处理器,这里只是注册,真正的调用是在 getBean 时候
7. 为上下文初始化 Message 源,即对不同语言的消息体进行国际化处理
8. 初始化应用消息广播器,并放入“app licatio EventMulticaster”bean中
9. 给子类来初始化其他的 bean
10. 在所有注册的 bean中查找listener bean 注册到消息广播器中
11. 初始化单实例(非惰性的)
12. 完成刷新过程,通知生命周期处理器 lifecycleProcessor 刷新过程,同时发出 ContextRefreshEvent 通知
下面,我们开始一步步来肢解这个 refresh() 方法
prepareRefresh 函数主要是做些准备工作,例如对系统属性及环境变量的初始化及验证
- protected void prepareRefresh() {
- //记录时间与状态
- this.startupDate = System.currentTimeMillis();
- this.closed.set(false);
- this.active.set(true);
-
- if (logger.isDebugEnabled()) {
- if (logger.isTraceEnabled()) {
- logger.trace("Refreshing " + this);
- }
- else {
- logger.debug("Refreshing " + getDisplayName());
- }
- }
-
- // 子类覆盖
- initPropertySources();
-
- //验证需要的配置文件是否已经放到环境中
- getEnvironment().validateRequiredProperties();
-
- // Store pre-refresh ApplicationListeners...
- if (this.earlyApplicationListeners == null) {
- this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
- }
- else {
- // Reset local application listeners to pre-refresh state.
- this.applicationListeners.clear();
- this.applicationListeners.addAll(this.earlyApplicationListeners);
- }
-
- // Allow for the collection of early ApplicationEvents,
- // to be published once the multicaster is available...
- this.earlyApplicationEvents = new LinkedHashSet<>();
- }
这个函数的最大的可用之处还是开放式设计,举个例子,软件在运行中有一个重要的设置项(如HOME)需要在系统环境变量中读取,,如果用户没有在系统环境变量中配置这个参数,那么工程应该不能工作。这一要求在spring中可以这么实现:
自定义容器启动类继承ClassPathXmlApplicationContext
- public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {
-
- public MyClassPathXmlApplicationContext(String ...configLocations) {
- super(configLocations);
- }
-
- @Override
- protected void initPropertySources() {
- //添加验证要求
- getEnvironment().setRequiredProperties("HOME");
- }
- }
- public static void main(String[] args) {
- MyClassPathXmlApplicationContext applicationContext = new MyClassPathXmlApplicationContext("application.xml");
- }
ApplicationContext是对BeanFactory的功能上的扩展,那么obtainFreshBeanFactory正是实现 BeanFactory的地方,这个方法是全文最重要的部分之一,这里将会初始化 BeanFactory、加载 Bean配置、注册 BeanDefinition 等等。以后所有的 BeanFactory 相关的操作其实是委托给这个实例来处理的。
- //AbstractApplicationContext 635行
- protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
- refreshBeanFactory();
- return getBeanFactory();
- }
- //AbstractRefreshableApplicationContext 124行
- protected final void refreshBeanFactory() throws BeansException {
- //销毁当前ApplicationContext已有的BeanFactory
- if (hasBeanFactory()) {
- destroyBeans();
- closeBeanFactory();
- }
- try {
- // 初始化一个 DefaultListableBeanFactory
- DefaultListableBeanFactory beanFactory = createBeanFactory();
- // 用于BeanFactory的序列化
- beanFactory.setSerializationId(getId());
- // 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
- customizeBeanFactory(beanFactory);
- // xml文件读取解析,加载 Bean 到 BeanFactory 中
- loadBeanDefinitions(beanFactory);
- synchronized (this.beanFactoryMonitor) {
- this.beanFactory = beanFactory;
- }
- }
- catch (IOException ex) {
- throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
- }
- }
定制BeanFactory
- //AbstractRefreshableApplicationContext 224行
- protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
- // 是否允许 Bean 定义覆盖
- if (this.allowBeanDefinitionOverriding != null) {
- beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
- }
- // 是否允许 Bean 间的循环依赖
- if (this.allowCircularReferences != null) {
- beanFactory.setAllowCircularReferences(this.allowCircularReferences);
- }
- }
BeanDefinition 的覆盖问题可能会有开发者碰到这个坑,就是在配置文件中定义 bean 时使用了相同的 id 或 name,默认情况下,allowBeanDefinitionOverriding 属性为 null,如果在同一配置文件中重复了,会抛错,但是如果不是同一配置文件中,会发生覆盖。
循环引用也很好理解:A 依赖 B,而 B 依赖 A。或 A 依赖 B,B 依赖 C,而 C 依赖 A。
默认情况下,Spring 允许单例属性的循环依赖,当然如果你在 A 的构造方法中依赖 B,在 B 的构造方法中依赖 A 是不行的。
loadBeanDefinitions
接下来是最重要的 loadBeanDefinitions(beanFactory) 方法了,这个方法将根据配置,加载各个 Bean,然后放到 BeanFactory 中。
读取配置的操作在 XmlBeanDefinitionReader 中,其负责加载配置、解析。
- //AbstractXmlApplicationContext 81行
- protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
- // Create a new XmlBeanDefinitionReader for the given BeanFactory.
- XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
-
- //进行环境变量配置
- beanDefinitionReader.setEnvironment(this.getEnvironment());
- beanDefinitionReader.setResourceLoader(this);
- beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
-
- //子类覆盖扩展,进行定制化配置
- initBeanDefinitionReader(beanDefinitionReader);
-
- loadBeanDefinitions(beanDefinitionReader);
- }
- //AbstractXmlApplicationContext 121行
- protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
- Resource[] configResources = getConfigResources();
- if (configResources != null) {
- reader.loadBeanDefinitions(configResources);
- }
- String[] configLocations = getConfigLocations();
- if (configLocations != null) {
- reader.loadBeanDefinitions(configLocations);
- }
- }
后续就是XmlBeanDefinitionReader对xml 文件的解析,并将加载后的BeanDefinition注册到DefaultListableBeanFactory中,具体过程请看Spring IOC源码解析篇二。
进入函数 prepareBeanFactory前,Spring已经完成了对配置的解析,ApplicationContext 在功能上的扩展也由此展开。
- //AbstractApplicationContext 645行
- protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
- //设置beanFactory的classLoader为当前context的classLoader
- beanFactory.setBeanClassLoader(getClassLoader());
- //设置beanFactory的表达式语言处理器,Spring3增加了表达式语言的支持,默认可以使用#{bean.xxx}的形式来调用相关属性值
- beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
- //为 beanFactory增加了一个默认propertyEditor,这个主要是对 bean 的属性等设置管理的一个个工具
- beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
-
- // Configure the bean factory with context callbacks.
- beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
-
- //设置了几个忽略自动装配的接口,如果某个 bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们
- beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
- beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
- beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
- beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
- beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
- beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
-
- //设置了几个自动装配的特殊规则,如果有 bean 依赖了以下几个,会注入这边相应的值
- beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
- beanFactory.registerResolvableDependency(ResourceLoader.class, this);
- beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
- beanFactory.registerResolvableDependency(ApplicationContext.class, this);
-
-
- beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
-
- //增加对AspectJ的支持
- if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
- beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
- // Set a temporary ClassLoader for type matching.
- beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
- }
-
- //添加默认的系统环境bean
- if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
- beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
- }
- if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
- beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
- }
- if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
- beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
- }
- }
上面函数主要进行了几个方面的扩展
增加对SpEL言的支持
增加对属性编辑器的支持
增加对一些内置类,比如EnvironmentAware、MessageSourceAware的信息注入
设置了依赖功能可忽略的接口
注册一些固定依赖的属性
增加 AspectJ的支持
将相关环境变量及属性注册以单例模式注册
- //PostProcessorRegistrationDelegate 55行
- public static void invokeBeanFactoryPostProcessors(
- ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
-
- // Invoke BeanDefinitionRegistryPostProcessors first, if any.
- Set<String> processedBeans = new HashSet<>();
-
- //对 BeanDefinitionRegistry容器类型的处理
- if (beanFactory instanceof BeanDefinitionRegistry) {
- BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
- List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
- List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
- //硬编码注册的后处理器
- for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
- if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
- BeanDefinitionRegistryPostProcessor registryProcessor =
- (BeanDefinitionRegistryPostProcessor) postProcessor;
- //对于BeanDefinitionRegistryPostProcessor类型,在BeanFactoryPostProcessor的基础上还有自己定义的方法,需要先调用
- registryProcessor.postProcessBeanDefinitionRegistry(registry);
- registryProcessors.add(registryProcessor);
- }
- else {
- regularPostProcessors.add(postProcessor);
- }
- }
-
-
- //配置注册的BeanDefinitionRegistryPostProcessor后处理器
- List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
-
-
- //执行实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的registry后置处理方法
- String[] postProcessorNames =
- beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
- for (String ppName : postProcessorNames) {
- if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
- currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
- processedBeans.add(ppName);
- }
- }
- //对后处理器排序
- sortPostProcessors(currentRegistryProcessors, beanFactory);
- //用于后面执行postProcessBeanFactory()
- registryProcessors.addAll(currentRegistryProcessors);
- //postProcessBeanFactory()前先执行自己的postProcessBeanDefinitionRegistry() invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
- currentRegistryProcessors.clear();
-
- //执行实现Ordered接口的BeanDefinitionRegistryPostProcessor
- postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
- for (String ppName : postProcessorNames) {
- if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
- currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
- processedBeans.add(ppName);
- }
- }
- sortPostProcessors(currentRegistryProcessors, beanFactory);
- registryProcessors.addAll(currentRegistryProcessors);
- invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
- currentRegistryProcessors.clear();
-
- //执行其他BeanDefinitionRegistryPostProcessors
- boolean reiterate = true;
- while (reiterate) {
- reiterate = false;
- postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
- for (String ppName : postProcessorNames) {
- if (!processedBeans.contains(ppName)) {
- currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
- processedBeans.add(ppName);
- reiterate = true;
- }
- }
- sortPostProcessors(currentRegistryProcessors, beanFactory);
- registryProcessors.addAll(currentRegistryProcessors);
- invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
- currentRegistryProcessors.clear();
- }
-
- // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
- //这里才执行postProcessBeanFactory()
- invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
- invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
- }
-
- else {
- // Invoke factory processors registered with the context instance.
- invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
- }
-
- //处理配置注册的BeanFactoryPostProcessor
- String[] postProcessorNames =
- beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
-
- // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
- // Ordered, and the rest.
- //对后处理进行分类
- List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
- List<String> orderedPostProcessorNames = new ArrayList<>();
- List<String> nonOrderedPostProcessorNames = new ArrayList<>();
- for (String ppName : postProcessorNames) {
- if (processedBeans.contains(ppName)) {
- // skip - already processed in first phase above
- }
- else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
- priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
- }
- else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
- orderedPostProcessorNames.add(ppName);
- }
- else {
- nonOrderedPostProcessorNames.add(ppName);
- }
- }
-
- //按照优先级排序
- sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
- invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
-
- //按照Ordered排序
- List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
- for (String postProcessorName : orderedPostProcessorNames) {
- orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
- }
- sortPostProcessors(orderedPostProcessors, beanFactory);
- invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
-
- //无序,直接调用
- List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
- for (String postProcessorName : nonOrderedPostProcessorNames) {
- nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
- }
- invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
-
- // Clear cached merged bean definitions since the post-processors might have
- // modified the original metadata, e.g. replacing placeholders in values...
- beanFactory.clearMetadataCache();
- }
从上面的方法中我们看到,对于BeanFactoryPostProcessor的处理主要分两种情况进行,一个是对于BeanDefinitionRegistry类的特殊处理,另一种是对普通的 BeanFactoryPostProcessor 进行处理,而对于每种情况都需要考虑硬编码注入注册的后处理器以及通过配置注入的后处理器。
现在我们来探索BeanPostProcessor,这里并不是调用,而是注注册,真正调用其实是在 bean的实例化阶段。
- //PostProcessorRegistrationDelegate 188行
- public static void registerBeanPostProcessors(
- ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
-
- String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
-
- // Register BeanPostProcessorChecker that logs an info message when
- // a bean is created during BeanPostProcessor instantiation, i.e. when
- // a bean is not eligible for getting processed by all BeanPostProcessors.
- int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
- beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
-
- // Separate between BeanPostProcessors that implement PriorityOrdered,
- // Ordered, and the rest.
- //使用PriorityOrdered保证顺序
- List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
- List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
- //使 Ordered 保证顺序
- List<String> orderedPostProcessorNames = new ArrayList<>();
- //无序 BeanPostProcessor
- List<String> nonOrderedPostProcessorNames = new ArrayList<>();
- for (String ppName : postProcessorNames) {
- if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
- BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
- priorityOrderedPostProcessors.add(pp);
- if (pp instanceof MergedBeanDefinitionPostProcessor) {
- internalPostProcessors.add(pp);
- }
- }
- else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
- orderedPostProcessorNames.add(ppName);
- }
- else {
- nonOrderedPostProcessorNames.add(ppName);
- }
- }
-
- //第1步,注册所有实现PriorityOrdered的BeanPostProcessor
- sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
- registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
-
- //第2步, 注册所有实现Ordered的BeanPostProcessor
- List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
- for (String ppName : orderedPostProcessorNames) {
- BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
- orderedPostProcessors.add(pp);
- if (pp instanceof MergedBeanDefinitionPostProcessor) {
- internalPostProcessors.add(pp);
- }
- }
- sortPostProcessors(orderedPostProcessors, beanFactory);
- registerBeanPostProcessors(beanFactory, orderedPostProcessors);
-
- //第3步, 注册所有无序的BeanPostProcessor
- List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
- for (String ppName : nonOrderedPostProcessorNames) {
- BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
- nonOrderedPostProcessors.add(pp);
- if (pp instanceof MergedBeanDefinitionPostProcessor) {
- internalPostProcessors.add(pp);
- }
- }
- registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
-
- //第4步,注册 MergedBeanDefitionPostProcessor类型的BeanPostProcessor
- sortPostProcessors(internalPostProcessors, beanFactory);
- registerBeanPostProcessors(beanFactory, internalPostProcessors);
-
- //添加ApplicationListener探测器
- beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
- }
initapplicationEventMulticaster方式比较简,无非考虑两种情况。
- //AbstractApplicationContext 762行
- protected void initApplicationEventMulticaster() {
- ConfigurableListableBeanFactory beanFactory = getBeanFactory();
- if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
- this.applicationEventMulticaster =
- beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
- if (logger.isTraceEnabled()) {
- logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
- }
- }
- else {
- this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
- beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
- if (logger.isTraceEnabled()) {
- logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
- "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
- }
- }
- }
作为广播器,一定是用于存放监昕器并在合适的时候调用监听器,那么我们不妨进入默认的广播器实现SimpleAppli cationEventMulticaster探究
-
- public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
- ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
- //遍历监听器,调用回调
- for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
- Executor executor = getTaskExecutor();
- if (executor != null) {
- executor.execute(() -> invokeListener(listener, event));
- }
- else {
- invokeListener(listener, event);
- }
- }
- }
-
-
- protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
- //包一层异常处理机制
- ErrorHandler errorHandler = getErrorHandler();
- if (errorHandler != null) {
- try {
- doInvokeListener(listener, event);
- }
- catch (Throwable err) {
- errorHandler.handleError(err);
- }
- }
- else {
- doInvokeListener(listener, event);
- }
- }
-
-
- private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
- try {
- //调用监听方法
- listener.onApplicationEvent(event);
- }
- catch (ClassCastException ex) {
- String msg = ex.getMessage();
- if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
- // Possibly a lambda-defined listener which we could not resolve the generic event type for
- // -> let's suppress the exception and just log a debug message.
- Log logger = LogFactory.getLog(getClass());
- if (logger.isDebugEnabled()) {
- logger.debug("Non-matching event type for listener: " + listener, ex);
- }
- }
- else {
- throw ex;
- }
- }
- }
- protected void registerListeners() {
- //注册硬编码的监听器
- for (ApplicationListener<?> listener : getApplicationListeners()) {
- getApplicationEventMulticaster().addApplicationListener(listener);
- }
-
- //注册配置文件的监听器
- String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
- for (String listenerBeanName : listenerBeanNames) {
- getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
- }
-
- //发布注册监听器之前已经发生的事件
- Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
- this.earlyApplicationEvents = null;
- if (earlyEventsToProcess != null) {
- for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
- getApplicationEventMulticaster().multicastEvent(earlyEvent);
- }
- }
- }
完成BeanFactory的初始化工作,其中包括ConversionService的设置、 配置冻结,以及非延迟加载的bean初始化工作。
- //AbstractApplicationContext 849行
- protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
- //初始化conversion服务,加载实现Converter接口的自定义类型转换器
- if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
- beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
- beanFactory.setConversionService(
- beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
- }
-
- // Register a default embedded value resolver if no bean post-processor
- // (such as a PropertyPlaceholderConfigurer bean) registered any before:
- // at this point, primarily for resolution in annotation attribute values.
- if (!beanFactory.hasEmbeddedValueResolver()) {
- beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
- }
-
- // 先初始化 LoadTimeWeaverAware 类型的 Bean之前也说过,这是 AspectJ
- String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
- for (String weaverAwareName : weaverAwareNames) {
- getBean(weaverAwareName);
- }
-
- // Stop using the temporary ClassLoader for type matching.
- beanFactory.setTempClassLoader(null);
-
- //冻结所有的 bean定义,spring开始预初始化,说明注册的 bean 定义将不被修改或进行任何进一步的处理
- beanFactory.freezeConfiguration();
-
- //开始初始化所有单例bean
- beanFactory.preInstantiateSingletons();
- }
- //DefaultListableBeanFactory 816行
- public void preInstantiateSingletons() throws BeansException {
- if (logger.isTraceEnabled()) {
- logger.trace("Pre-instantiating singletons in " + this);
- }
-
- // Iterate over a copy to allow for init methods which in turn register new bean definitions.
- // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
- List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
-
- // Trigger initialization of all non-lazy singleton beans...
- for (String beanName : beanNames) {
- //合并父 Bean 中的配置
- RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
- // 加载非抽象、非懒加载的 singletons。如果配置了 'abstract = true',那是不需要初始化的
- if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
- if (isFactoryBean(beanName)) {
- //FactoryBean的话,在beanName前面加上‘&’ 符号,再调用 getBean
- Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
- if (bean instanceof FactoryBean) {
- final FactoryBean<?> factory = (FactoryBean<?>) bean;
- //判断当前FactoryBean是否是 martFactoryBean的实现
- boolean isEagerInit;
- if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
- isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
- ((SmartFactoryBean<?>) factory)::isEagerInit,
- getAccessControlContext());
- }
- else {
- isEagerInit = (factory instanceof SmartFactoryBean &&
- ((SmartFactoryBean<?>) factory).isEagerInit());
- }
- if (isEagerInit) {
- getBean(beanName);
- }
- }
- }
- else {
- //对于普通的Bean,只要调用getBean(beanName)这个方法就可以进行初始化了
- getBean(beanName);
- }
- }
- }
-
- // 到这里说明所有的非懒加载的 singleton beans 已经完成了初始化
- // 如果我们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里得到回调
- for (String beanName : beanNames) {
- Object singletonInstance = getSingleton(beanName);
- if (singletonInstance instanceof SmartInitializingSingleton) {
- final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
- if (System.getSecurityManager() != null) {
- AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
- smartSingleton.afterSingletonsInstantiated();
- return null;
- }, getAccessControlContext());
- }
- else {
- smartSingleton.afterSingletonsInstantiated();
- }
- }
- }
- }
bean的完整初始化过程在getBean()方法中实现,请移步到SpringIOC源码解析篇三详细浏览。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。