美文网首页
6. 容器的功能扩展(二)

6. 容器的功能扩展(二)

作者: 凭窗听风 | 来源:发表于2019-05-08 22:33 被阅读0次

spring源码学习笔记,要点归纳和代码理解

前言

上一节讲述了容器初始化过程中beanFactory的创建以及bean配置的解析过程.本节将会继续容器的初始化过程解析.

BeanFactory的后处理

1. 注册和激活BeanFactoryPostProcessor, 工厂后置处理器 invokeBeanFactoryPostProcessors(beanFactory)

其方法调用栈为:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

        // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
        // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }

可以看到这里使用了设计模式中的 委托模式
实际上这里执行了两种后处理器的注册:

  1. 先执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
  2. 然后执行其父接口的postProcessBeanFactory方法
  3. BeanFactoryPostProcessor的postProcessBeanFactory方法.
    执行顺序是一致的.都按照PriorityOrdered->Ordered->其他后处理器
    需要注意的是BeanFactoryPostProcessor处理器是全局的后处理器,在BeanFactory完成初始化之后进行注册和激活,
    其主要用于在完成BeanDefinition注册和BeanFactory初始化之后,对Bean进行初始化之前的逻辑.
    将中文注释的代码贴过来如下:
public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        Set<String> processedBeans = new HashSet<>();

        // 注册和激活BeanDefinitionRegistryPostProcessor
        // 注册和激活过程按指定的顺序
        // 先执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
        // 然后执行其父接口的postProcessBeanFactory方法
        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;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 首先注册实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
            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);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // 接下来注册实现了Ordered接口的BeanDefinitionRegistryPostPostProcessor
            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();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // 最后注册剩下所有的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.
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            // Invoke factory processors registered with the context instance.
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }
        //注册和激活BeanFactoryPostProcessor

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 执行顺序也按照PriorityOrdered、Ordered和其他
        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);
            }
        }

        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        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();
    }

2. 注册BeanPostProcessor 对象后置处理器.

这里只进行对象后置处理器的注册,其调用是在对应bean进行初始化之后进行
注册循序也按照PriorityOrdered->Ordered->其他处理器
在方法的最后硬编码了一句beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext))
我查了一下ApplicationListenerDetector这个注册器的作用,是将实现了ApplicationListener接口的Bean添加到容器的监听器列表.

3. 为上下文环境初始化Message源,国际化处理 initMessageSource();

4. 初始化ApplicationEventMulticaster

初始化事件广播器,对发布的事件进行监听,调用执行监听器对应的方法.监听器需要在容器进行注册.
这里写一个小demo看下用法.

  1. 定义监听事件
public class TestEvent extends ApplicationEvent {

    private String msg;
    
    public TestEvent(Object source) {
        super(source);
    }

    public TestEvent(Object source, String msg) {
        super(source);
        this.msg = msg;
    }

    public void afterEventHappen() {
        System.out.println(String.format("at %s event happens, and message is %s" , new Date(super.getTimestamp()), msg));
    }
}
  1. 定义监听器
public class TestListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof TestEvent) {
            TestEvent testEvent = (TestEvent) event;
            ((TestEvent) event).afterEventHappen();
        }
    }
}
  1. 注册监听器

    <bean id = "testListener" class = "com.pctf.contextextend.listener.TestListener"></bean>
  1. 测试,发布事件
public class ListenerTest {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("listener-config.xml");
        applicationContext.publishEvent(new TestEvent(ListenerTest.class, "发布测试事件"));
    }
}

可以看到发布事件后,控制台输出

其实现步骤是:

  1. 容器初始化applicationEventMulticaster,如果用户自定义,则使用用户自定义的时间广播器,否则使用默认的SimpleApplicationEventMulticaster
  2. 注册监听器registerListeners,在onFresh()方法中调用
  3. applicationContext发布事件,调用广播器的multicastEvent方法
  4. 广播器获取所有容器中注册的listener,执行listener中的onApplicationEvent方法,每个监听器都可以获取到产生的事件,由监听器本身决定是否处理事件
    其中SimpleApplicationEventMulticaster广播器的multicastEvent方法如下:
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        Executor executor = getTaskExecutor();
        for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
            if (executor != null) {
                executor.execute(() -> invokeListener(listener, event));
            }
            else {
                invokeListener(listener, event);
            }
        }
    }

我们看到其支持同步和异步两种方式发布事件,默认不会创建执行器, 也就是同步执行,我们在测试类中手动给广播器添加一个executor

public static void main(String[] args) {
        AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext("listener-config.xml");
        // 我这里是直接将AbstractApplicationContext中的getApplicationEventMulticaster方法改为public的,实际上这个方法是没有
        //修饰符的,既包可见,生产中需要继承后改为public.这也体现了对扩展开放对改写关闭的原则
        SimpleApplicationEventMulticaster applicationEventMulticaster = (SimpleApplicationEventMulticaster) applicationContext.getApplicationEventMulticaster();
        applicationEventMulticaster.setTaskExecutor(Executors.newFixedThreadPool(4));
        applicationContext.publishEvent(new TestEvent(ListenerTest.class, "发布测试事件"));
    }

debug后看到事件处理已经变成了使用我们创建的执行器


5.注册监听器

贴下代码,不做详解

protected void registerListeners() {
        // Register statically specified listeners first.
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let post-processors apply to them!
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // Publish early application events now that we finally have a multicaster...
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

完成beanFactory初始化

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // Initialize conversion service for this context.
        // 将实现了ConversionService的实例注册到容器,可以实现转换器的功能
        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));
        }

        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        // 对于LoadTimeWeaverAware的实例需要提前注册
        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);

        // Allow for caching all bean definition metadata, not expecting further changes.
        // 在此冻结所有配置项
        beanFactory.freezeConfiguration();

        // Instantiate all remaining (non-lazy-init) singletons.
        // 初始化所有剩余的单例
        beanFactory.preInstantiateSingletons();
    }

这里书中给的标题是初始化非延时加载实例,实际上是完成实例工厂的初始化,包括

  1. 注册自定义的类型转换器
  2. 注册值解析器,解析注解注入的属性值
  3. 对于加载时的织入对象需要提前注册
  4. 冻结所有实例配置
  5. 初始化所有剩余的单例

完成初始化 finishRefresh

protected void finishRefresh() {
        // Clear context-level resource caches (such as ASM metadata from scanning).
        // 清除容器缓存
        clearResourceCaches();

        // Initialize lifecycle processor for this context.
        // 初始化lifecycleProcessor,不指定的话会创建一个DefaultLifecycleProcessor
        initLifecycleProcessor();

        // Propagate refresh to lifecycle processor first.
        // 执行onFresh方法
        getLifecycleProcessor().onRefresh();

        // Publish the final event.
        // 发布一个容器刷新完成的事件
        publishEvent(new ContextRefreshedEvent(this));

        // Participate in LiveBeansView MBean, if active.
        // 这一步
        LiveBeansView.registerApplicationContext(this);
    }

主要执行的步骤见注释,其中DefaultLifecycleProcessor的onfresh方法实际上是为所有实现lifeCycle的实例启动start方法.代码如下:

private void startBeans(boolean autoStartupOnly) {
        Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
        Map<Integer, LifecycleGroup> phases = new HashMap<>();
        lifecycleBeans.forEach((beanName, bean) -> {
            if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
                int phase = getPhase(bean);
                LifecycleGroup group = phases.get(phase);
                if (group == null) {
                    group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                    phases.put(phase, group);
                }
                group.add(beanName, bean);
            }
        });
        if (!phases.isEmpty()) {
            List<Integer> keys = new ArrayList<>(phases.keySet());
            Collections.sort(keys);
            for (Integer key : keys) {
                phases.get(key).start();
            }
        }
    }

总结

至此,扩展容器的初始化过程和在初始化中对于beanFactory的扩展已经很粗略的浏览了一遍了,可以看到applicationContext功能的强大和极高的可扩展性,实际上在文章编写过程中反复的调试阅读代码可以学到很多,比如各种设计模式的实际应用:观察者模式,工厂模式,委托模式等等;如何精确地在需要扩展的地方添加自己的代码;还有大量函数式编程等等...
跟随书籍通读一遍代码只是简单理清思路,了解整个容器的运行原理,大量细节以及为什么要这样设计还需要反复阅读才能理解,以及书中只涉及到初始化相关逻辑的理解,对于容器销毁的过程还没有提及,可以说spring容器还有很多探究和摸索的地方.

相关文章

网友评论

      本文标题:6. 容器的功能扩展(二)

      本文链接:https://www.haomeiwen.com/subject/oluboqtx.html