当前位置: 首页 > news >正文

浙江建设厅网站施工员报名常见的网络营销方式有哪几种

浙江建设厅网站施工员报名,常见的网络营销方式有哪几种,南宁网站建设推广,网站建设维护外包前言 Spring框架中最重要的肯定是IOC容器,那么其如何进行初始化,就是通过refresh()这个方法,无论是单独使用Spring框架,还是SpringBoot,最终都会通过执行到这个方法,那么下面会介绍一下这个方法 一、IOC容…

前言

Spring框架中最重要的肯定是IOC容器,那么其如何进行初始化,就是通过refresh()这个方法,无论是单独使用Spring框架,还是SpringBoot,最终都会通过执行到这个方法,那么下面会介绍一下这个方法

一、IOC容器初始化过程

对于单独测试Spirng框架的场景,有两个常见的高级容器 AnnotationConfigApplicationContextClassPathXmlApplicationContext,在这两个类的构造方法,都会使用到refresh()来刷新容器

AnnotationConfigApplicationContext

AnnotationConfigApplicationContext会通过扫描配置类来创建IOC容器

    @Testpublic void m1() {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AspectConfig.class);MathCalculator mathCalculator = context.getBean(MathCalculator.class);int ans = mathCalculator.div(10, 5);System.out.println("结果:" + ans);}public AnnotationConfigApplicationContext(Class<?>... componentClasses) {// 调用无参构造方法this();// 注册新的组件register(componentClasses);// 刷新容器refresh();}

构造方法

public AnnotationConfigApplicationContext() {StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");// 创建注解Readerthis.reader = new AnnotatedBeanDefinitionReader(this);createAnnotatedBeanDefReader.end();// 创建类扫描this.scanner = new ClassPathBeanDefinitionScanner(this);
}

创建的AnnotatedBeanDefinitionReader

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {this(registry, getOrCreateEnvironment(registry));
}public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");Assert.notNull(environment, "Environment must not be null");this.registry = registry;this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);// 这里最后一行很关键,注册了一些核心的BeanPostProcessorAnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

下面的方法就是容器启动时初始化,注册一些基础使用的类,其中有一个需要着重看一眼的就是负责处理@Configuration的后置处理器ConfigurationClassPostProcessor

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {registerAnnotationConfigProcessors(registry, null);
}public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);// 这里是最重要的,就是注册用来处理@Configuration注解的后置处理器if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}// 省略了一些代码return beanDefs;
}

ClassPathXmlApplicationContext

加载bean的xml文件,底层也是通过refresh()方式

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {super(parent);setConfigLocations(configLocations);if (refresh) {refresh();}
}

二、refresh()

方法简介

refresh()ConfigurableApplicationContext中的接口,子类AbstractApplicationContext重写了该方法,负责初始化IOC容器
在这里插入图片描述

该方法中总共包含12个方法,大体的工作内容介绍:

  1. 刷新前的准备工作
  2. 获取Bean工厂
  3. 工厂前期的准备
  4. 子类重写方法,可以对Bean工厂进行扩展
  5. 执行BeanFactory的后置处理器
  6. 注册Bean的后置处理器
  7. 初始化消息源,负责国际化
  8. 初始化上下文事件
  9. 子类重写方法,初始化其它特殊bean
  10. 注册监听器
  11. 工厂基本创建完毕,剩余的收尾工作
  12. 刷新完成,剩余的收尾工作
	@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// Prepare this context for refreshing. // <1> 准备预处理:记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写prepareRefresh();// <2> 告诉子类去刷新bean工厂,此方法解析配置文件并将bean信息存储到beanDefinition中,注册到BeanFactory//(但是未被初始化,仅将信息写到了beanDefination的map中)**重点方法,下面的操作都基于这个beanFactory进行的ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.// <3> 设置beanFactory的基本属性:类加载器,添加多个beanPostProcesserprepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.// <4> 扩展机制: 允许上下文子类中对bean工厂进行后处理postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");/**************************以上是BeanFactory的创建及预准备工作  ****************/// Invoke factory processors registered as beans in the context.// <5> 调用BeanFactoryPostProcessor各个实现类的方法 invokeBeanFactoryPostProcessors(beanFactory);// <6> 注册 BeanPostProcessor 的实现类registerBeanPostProcessors(beanFactory);beanPostProcess.end();// <7> 初始化ApplicationContext的MessageSource组件(资源文件),如国际化文件,消息解析,绑定等initMessageSource();// <8> 初始化ApplicationContext事件广播器initApplicationEventMulticaster();// <9> 在特定上下文子类中初始化其他特殊beanonRefresh();// <10> 获取所有的事件监听器,并将监听器注册到事件广播器registerListeners();// <11> 初始化所有不是懒加载的singleton beanfinishBeanFactoryInitialization(beanFactory);// <12> 广播事件: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 {// 重置 Spring 核心中的公共自省缓存,因为我们可能不再需要单例 bean 的元数据......// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();contextRefresh.end();}}}

<1> prepareRefresh() 刷新准备

1、prepareRefresh()刷新前的预处理;1)、initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法;2)、getEnvironment().validateRequiredProperties();检验属性的合法等3)、earlyApplicationEvents= new LinkedHashSet<>();保存容器中的一些早期的事件;
	/*** Prepare this context for refreshing, setting its startup date and  容器刷新的准备工作,设置启动时间* active flag as well as performing any initialization of property sources. 以及初始化属性源*/protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis(); // 获取当前时间// 设置关闭状态false 启动状态truethis.closed.set(false);this.active.set(true);// 输出日志if (logger.isDebugEnabled()) {if (logger.isTraceEnabled()) {logger.trace("Refreshing " + this);}else {logger.debug("Refreshing " + getDisplayName());}}// Initialize any placeholder property sources in the context environment.// 初始化一些属性在容器环境中 留给子类重写initPropertySources();// Validate that all properties marked as required are resolvable:// see ConfigurablePropertyResolver#setRequiredProperties// 验证属性的是否合法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<>();}

a> initPropertySources()

是个空方法,留给子类重写自定义

	/*** <p>Replace any stub property sources with actual instances.* @see org.springframework.core.env.PropertySource.StubPropertySource* @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources*/protected void initPropertySources() {// For subclasses: do nothing by default.}

b> validateRequiredProperties()

验证请求属性,方法很简单,循环遍历,判断是否为Null,存在则直接抛出异常MissingRequiredPropertiesException,该异常为自定义异常类

	public void validateRequiredProperties() {// 创建异常信息MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();Iterator var2 = this.requiredProperties.iterator();// 遍历 找到空的keywhile(var2.hasNext()) {String key = (String)var2.next();if (this.getProperty(key) == null) {ex.addMissingRequiredProperty(key);}}// 存在空的直接抛出异常if (!ex.getMissingRequiredProperties().isEmpty()) {throw ex;}}

<2> obtainFreshBeanFactory() 获取bean工厂

该方法很简单,获取到对应的bean工厂,类型为DefaultListableBeanFactory,也是Spring中功能最全的IOC容器

	/*** Tell the subclass to refresh the internal bean factory.* @return the fresh BeanFactory instance 返回容器示例* @see #refreshBeanFactory()* @see #getBeanFactory()*/protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// 刷新容器refreshBeanFactory();// 通过getter方法获取到Bean工厂返回,其实就是默认的DefaultListableBeanFactoryreturn getBeanFactory();}

a> refreshBeanFactory()

GenericApplicationContext类初始化的时候,就创建了一个默认的BeanFactory,然后这里会设置Id

  1. 创建的beanFactory是DefaultListableBeanFactory类型
  2. 该beanFactory在类初始化的时候就创建了
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {// 构造方法public GenericApplicationContext() {// 这里也代表了DefaultListableBeanFactory是Spring中最核心的类this.beanFactory = new DefaultListableBeanFactory();}/*** Do nothing: We hold a single internal BeanFactory and rely on callers* to register beans through our public methods (or the BeanFactory's).* @see #registerBeanDefinition*/@Overrideprotected final void refreshBeanFactory() throws IllegalStateException {if (!this.refreshed.compareAndSet(false, true)) {throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");}// 这个id就是 org.springframework.context.annotation.AnnotationConfigApplicationContext@5b0abc94this.beanFactory.setSerializationId(getId());}	// ...   
}

<3> prepareBeanFactory() 准备工厂

3、prepareBeanFactory(beanFactory);BeanFactory的预准备工作(BeanFactory进行一些设置);1)、设置BeanFactory的类加载器、支持表达式解析器...2)、添加部分BeanPostProcessor【ApplicationContextAwareProcessor】3)、设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;4)、注册可以解析的自动装配;我们能直接在任何组件中自动注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext5)、添加BeanPostProcessor【ApplicationListenerDetector】6)、添加编译时的AspectJ7)、给BeanFactory中注册一些能用的组件;environment【ConfigurableEnvironment】、systemProperties【Map<String, Object>】、systemEnvironment【Map<String, Object>
	/*** Configure the factory's standard context characteristics,  配置工厂启动时上下文特征* such as the context's ClassLoader and post-processors.	  例如容器的类加载器和后置处理器* @param beanFactory the BeanFactory to configure*/protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.// 1.设置Bean的类加载器beanFactory.setBeanClassLoader(getClassLoader());if (!shouldIgnoreSpel) {// 设置支持相关表达式语言的解析器beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));}// 添加属性的编辑注册器beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.// 2.添加部分后置处理器【ApplicationContextAwareProcessor】beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 3.设置忽略自动装配的接口beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.// 4.注册可以解析的自动装配beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// Register early post-processor for detecting inner beans as ApplicationListeners.// 5.添加BeanPostProcessor【ApplicationListenerDetector】事件监听beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.if (!NativeDetector.inNativeImage() && 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()));}// Register default environment beans.// 给BeanFactory中注册一些能用的组件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());}if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());}}

<4> postProcessBeanFactory() 子类重写扩展

提供的扩展机制,子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置

	/*** Modify the application context's internal bean factory after its standard* initialization. All bean definitions will have been loaded, but no beans* will have been instantiated yet. This allows for registering special* BeanPostProcessors etc in certain ApplicationContext implementations.* @param beanFactory the bean factory used by the application context*/protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {}

<5> invokeBeanFactoryPostProcessors()

a> 方法入口

这个方法会继续调用一个包装类中的方法,负责执行后置处理器,其中的参数getBeanFactoryPostProcessors()会获取后置处理器,这里获取的后置处理器是框架初始化需要的,会被优先执行

但需要注意的是,并不是Spring框架需要的,在实际测试过程中,如果使用SpringBoot,可以成功获取到,如果单独启动Spring,则啥也没有

	/*** Instantiate and invoke all registered BeanFactoryPostProcessor beans,* respecting explicit order if given.* <p>Must be called before singleton instantiation.*/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 (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}

在这里插入图片描述
在这里插入图片描述

上面两张图也说明了问题,如果想在Spring框架基础上封装其它框架,例如经典的SpringBoot,Spring会先执行SpringBoot初始化需要的后置处理器,保证核心框架先顺利启动,然后再执行其它依赖和手写的后置处理器

当然侧面证明了Spring提供的良好的扩展性能,再启动Spring的时候,优先执行二次封装的代码,最后在是其它依赖和自己写的代码

b> 接口介绍

下面方法会用到这2个接口,这里先介绍一下

BeanFactoryPostProcessor

BeanFactoryPostProcessor的执行时机为容器初始化后,实例化Bean前,Spring允许在这个时候可以对Bean工厂进行修改,一种良好的扩展性能

public interface BeanFactoryPostProcessor {// 通过参数ConfigurableListableBeanFactory可以获取到定义信息void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

使用示例

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("调用MyBeanFactoryPostProcessor的postProcessBeanFactory");BeanDefinition bd = beanFactory.getBeanDefinition("mathCalculator");System.out.println("属性值------>" + bd.getPropertyValues().toString());MutablePropertyValues pv = bd.getPropertyValues();if (pv.contains("remark")) {pv.addPropertyValue("remark", "把备注信息修改一下");}bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);}
}

BeanDefinitionRegistryPostProcessor

  1. 通过下面的代码,看到它继承了BeanFactoryPostProcessor
  2. 它会在所有的bean定义信息还未被加载,将要被加载的时候执行,可以对BeanDefiniton进行增删改查
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {/*** Modify the application context's internal bean definition registry after its* standard initialization. All regular bean definitions will have been loaded,* but no beans will have been instantiated yet. This allows for adding further* bean definitions before the next post-processing phase kicks in.* @param registry the bean definition registry used by the application context* @throws org.springframework.beans.BeansException in case of errors*/void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

c> 方法分析

  1. 首先参数传递过来的后置处理器,该参数上面已经介绍了,这些是框架启动需要的,例如SpringBoot,如果是单独的Spring启动则为空集合
  2. 判断是否实现了BeanDefinitionRegistry该接口,只有IOC容器实现了该接口,才代表允许其它代码操作BeanDefinition,看成一个开关入口
  3. 执行第1步:首先执行SpringBoot框架需要的BeanDefinitionRegistryPostProcessor,需要先把框架处理完毕
  4. 执行第2步:执行其它依赖和开发人员写的BeanDefinitionRegistryPostProcessor
    1. 优先执行实现了PriorityOrdered接口的
    2. 次之执行实现了Ordered接口的
    3. 执行剩余的后置处理器
  5. 接下来会先执行一批BeanFactoryPostProcessor,上面也介绍了这2个接口是继承关系,所以重写子类方法必须也带上父类方法,上面执行的BeanDefinitionRegistryPostProcessor后置处理器,肯定也有BeanFactoryPostProcessor的方法,这里需要执行,这里启动就是2部分
    1. 先执行上面这些实现了BeanDefinitionRegistryPostProcessor接口,里面肯定重写了父类BeanFactoryPostProcessor,需要先执行
    2. 参数传递过来的BeanFactoryPostProcessor,这些也需要先执行
  6. 到此上面已经把BeanDefinitionRegistryPostProcessor处理完毕,接下来就是BeanFactoryPostProcessor,这里会和上面一样,先处理PriorityOrdered,次之Ordered,最后剩余的
  7. 总结:代码非常长,理解了很简答,总体思想就是先执行框架启动需要的,然后在执行自己写的,先执行BeanDefinitionRegistryPostProcessor,后BeanFactoryPostProcessor
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {// Invoke BeanDefinitionRegistryPostProcessors first, if any.// 执行BeanDefinitionRegistryPostProcessors的实现类【首先调用】Set<String> processedBeans = new HashSet<>();// 实现该接口才允许操作BeanDefinition,当然DefaultListableBeanFactory肯定实现了if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();// <1> 处理参数传递过来的后置处理器,这些是Spring启动需要的// 按照实现接口分类存进去, 并且优先执行实现了BeanDefinitionRegistryPostProcessor的后置方法,系统类的先执行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 优先级排序接口的BeanDefinitionRegistryPostProcessors子类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, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.// 第二步 执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessorspostProcessorNames = 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, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.// 最后 执行剩余的BeanDefinitionRegistryPostProcessorsboolean 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, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();}// Now, invoke the postProcessBeanFactory callback of all processors handled so far.// 调用到目前为止处理的所有处理器的 postProcessBeanFactory() 回调// 这里会有一个疑问: postProcessBeanFactory()不是下面很多行代码负责执行吗?咋这里就执行了// 首先 registryProcessors是上面实现了子类接口,那么父类肯定也给重写,那么这里先调用// 其次 regularPostProcessors到目前位置有数据,肯定是框架启动需要的后置处理器,也要先执行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);}}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.// 第一步 执行实现 PriorityOrdered 接口的 BeanFactoryPostProcessorssortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.// 第二步 执行实现 Ordered 接口的 BeanFactoryPostProcessorsList<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();}

d> 重要Debug

如下截图所示,Spring框架负责解析@Configuration配置类的是后置处理器ConfigurationClassPostProcessor,它会负责扫描各种类,把bean包装成BeanDefinition存入IOC容器,具体后续会介绍ConfigurationClassPostProcessor
在这里插入图片描述

<6> registerBeanPostProcessors()

顾名思义,注册Bean后置处理器,它负责拦截Bean的创建,这样我们就可以通过该拦截对Bean添加自定义逻辑,例如Aop功能,就是通过注解添加了一个后置处理器,然后在创建Bean的时候,对其进行代理,达到增强的目的

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
  1. 获取所有的BeanPostProcessor后置处理器
  2. 先注册PriorityOrdered优先级接口的BeanPostProcessor
  3. 再注册Ordered接口的
  4. 最后注册没有实现任何优先级接口的
  5. 最终注册MergedBeanDefinitionPostProcessor
  6. 注册一个ApplicationListenerDetector
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// 1.获取所有实现 BeanPostProcessor 接口的后置处理器String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// 2.记录数量 = 框架中已经存在的 + 稍后会注入的数量 + 下一行代码注入的1个后置处理器int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;// 新注册的处理器 BeanPostProcessorChecker 主要用于记录信息beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// Separate between BeanPostProcessors that implement PriorityOrdered,// Ordered, and the rest.// 3.分类存储// 实现PriorityOrdered接口的List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();// 实现Ordered接口的name集合List<String> orderedPostProcessorNames = new ArrayList<>();// 定义普通的name集合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);}}// 4.先注册实现 PriorityOrdered 接口的// First, register the BeanPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// 5.次之注册实现 Ordered 接口的// Next, register the BeanPostProcessors that implement Ordered.List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());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);// 5.最后注册普通的后置处理器// Now, register all regular BeanPostProcessors.List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// 6.注册实现了 MergedBeanDefinitionPostProcessor 接口的// Finally, re-register all internal BeanPostProcessors.sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);// Re-register post-processor for detecting inner beans as ApplicationListeners,// moving it to the end of the processor chain (for picking up proxies etc).// 7.重新注册用于将内部 bean 检测为 ApplicationListeners 的后处理器,将其移动到处理器链的末尾(用于获取代理等)beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

<7> initMessageSource() 国际化

MessageSource是负责国际化功能的,下面的代码大体很简单,如果已经存在国际化组件,就一顿操作处理,没有就注册个新的

那么想一下,之前怎么可能会有该bean?那肯定是开发人员自定义的国际化组件,如果存在则在第<5>步的时候已经解析完毕,执行到该方法,肯定就可以获取到

那么在把下面这个方法概述一下:如果开发人员自定义了国际化组件,那就用自己写的,按照固定的格式处理一下,否则就用默认的国际化组件

这同样体现了Spring框架良好的扩展机制,后续会编写单独的文章介绍MessageSource

protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();// 如果存在该bean,则代表开发人员自定义了国家化组件if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// Make MessageSource aware of parent MessageSource.if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;if (hms.getParentMessageSource() == null) {// Only set parent context as parent MessageSource if no parent MessageSource// registered already.hms.setParentMessageSource(getInternalParentMessageSource());}}if (logger.isTraceEnabled()) {logger.trace("Using MessageSource [" + this.messageSource + "]");}}else { // 否则使用默认的国际化组件// Use empty MessageSource to be able to accept getMessage calls.DelegatingMessageSource dms = new DelegatingMessageSource();dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);if (logger.isTraceEnabled()) {logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");}}
}

<8> initApplicationEventMulticaster()

下面这个方法大体逻辑和第<7>步一致,如果存在该bean,则代表开发人员自定义了该功能,则处理一下,否则注册一个默认的

ApplicationEventMulticaster是Spring中事件广播器接口,负责事件的广播发布。

通过名字可以看出它就是一个广播站,可以把监听器注册到我这里来,有事件通过我进行发布。也可以理解为MQ种的发布-订阅模式,监听器在这里进行订阅,有消息通过我进行发布

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() + "]");}}
}

ApplicationEventMulticaster

上面看懂了该组件的功能,这里看接口就好理解了,负责注册监听器的,负责发布事件的

public interface ApplicationEventMulticaster {// 注册监听器void addApplicationListener(ApplicationListener<?> listener);void addApplicationListenerBean(String listenerBeanName);// 移除监听器void removeApplicationListener(ApplicationListener<?> listener);void removeApplicationListenerBean(String listenerBeanName);void removeAllListeners();// 发布事件void multicastEvent(ApplicationEvent event);void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);}

<9> onRefresh() 子类重写扩展

在特定上下文子类中初始化其他特殊bean

protected void onRefresh() throws BeansException {// For subclasses: do nothing by default.
}

<10> registerListeners()

在上面第<8>步,注册了一个事件广播器,该方法负责把监听器注册到里面

protected void registerListeners() {// 1.向事件分发器注册监听器,这些是通过配置文件读取的// Register statically specified listeners first.for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);}// 2.向事件分发器注册外部加入的监听器,但不实例化// 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);}// 3.发布早期的事件// 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);}}
}

<11> finishBeanFactoryInitialization()

通过名字可以看出是完成BeanFactory的初始化,一个收尾方法,相当于一个bean工厂大部分已经完成了,还剩余零零散散的辅助bean需要依次注入

在这个方法中需要关注的是最后1行,这里会实例化未设置懒加载的单例bean

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 1.为此上下文初始化转换服务// Initialize conversion service for this context.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.// 2.如果之前没有注册任何 bean 后处理器(例如 PropertyPlaceholderConfigurer bean),则注册一个默认的嵌入值解析器:此时,主要用于注释属性值的解析if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));}// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.// 3.通过 getBean() 尽早的注册LoadTimeWeaverAwareString[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.   // 4.停止使用临时类加载器进行类型匹配beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes. // 5.允许缓存所有 bean 定义元数据,而不是期望进一步的更改beanFactory.freezeConfiguration();// 6.Instantiate all remaining (non-lazy-init) singletons.// 初始化未懒加载的单例beanbeanFactory.preInstantiateSingletons();
}

a> preInstantiateSingletons

子类DefaultListableBeanFactory重写了该方法

功能:循环所有的Bean名称,遍历判断,然后实例化,最后调用回调

// DefaultListableBeanFactory	@Overridepublic 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.// 1.获取全部的BeanNameList<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...// 2.实例化所有非懒加载的单实例Beanfor (String beanName : beanNames) RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);// 非抽象 && 单实例 && 非懒加载if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {// 类型判断是否为FactoryBean,  FactoryBean在后续章节也有讲解if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;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);}}}// Trigger post-initialization callback for all applicable beans...// 触发所有适用 bean 的初始化后回调for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}}

<12> finishRefresh()

上面已经把BeanFactory初始化完毕,那么这个IOC容器就接近尾声了,接下来就是一些后续工作

protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).// 清除上下文级资源缓存clearResourceCaches();// Initialize lifecycle processor for this context.// 为此上下文初始化生命周期处理器initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);
}

ingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}


## <12> finishRefresh()上面已经把`BeanFactory`初始化完毕,那么这个IOC容器就接近尾声了,接下来就是一些后续工作```java
protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).// 清除上下文级资源缓存clearResourceCaches();// Initialize lifecycle processor for this context.// 为此上下文初始化生命周期处理器initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);
}
http://www.shuangfujiaoyu.com/news/29586.html

相关文章:

  • 推荐seo网站诊断
  • 重庆网站建设零臻靠谱友情链接互换网站
  • discuz 做网站可以吗网站注册要多少钱
  • 取公司名称大全简单大气优化大师下载安装app
  • 建设网站就选用什么样的公司宁波seo外包推广公司
  • 建设网站的主要流程网络营销的概念和特征
  • 用苹果手机做网站时空seo助手
  • 免费申请一个不花钱网站网络营销策划案怎么写
  • 中国新闻社官方网站长沙网络推广只选智投未来
  • 湛江怎样建设自己的网站免费个人自助建站
  • 信息流广告案例seo服务外包费用
  • 酒店网站开发排行榜哪个网站最好
  • Wordpress教程推荐沈阳网络seo公司
  • 网站首页排名seo搜索优化朋友圈广告推广代理
  • 宁波商城网站建设cpa广告联盟
  • 北京网站建设seo2baidu网站运营包括哪些内容
  • 辽宁建设执业信息网站友情链接是外链吗
  • 河北建设厅网站首页百度网站网址是多少
  • 南昌手机网站建设媒体资源网
  • 网站上点击图片局部放大如何做重庆店铺整站优化
  • wordpress加速网站插件简单的网页设计
  • 呼和浩特市网站建设公司海外seo推广公司
  • 淘客怎么做网站单页太原百度快速优化
  • 网站背景图片怎么做腾讯nba新闻
  • shanxi建设银行网站首页怎么推广产品
  • 新年电子贺卡免费制作软件appseo推广知识
  • 网站诊断表网站客服系统
  • 秦皇岛做网站多少钱免费网站大全
  • 企业网站建设费用入什么科目天津seo优化排名
  • 龙武工会网站怎么做seo排名点击工具