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

Spring-IOC源码解析

容器创建过程

Spring容器的refresh方法

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// 1. 进行创建Bean工厂的前置处理prepareRefresh();// 2. 创建容器,并且进行一些必要的设置工作ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 3. 对创建好的容器进行准备工作prepareBeanFactory(beanFactory);try {// 4. Bean工厂初始化之后的后置处理器 空方法 主要用于子类实现之后注册一些必备的组件postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// 5. 执行Bean工厂的后置处理器 (按照优先级)invokeBeanFactoryPostProcessors(beanFactory);// 6. 组件注册的后置处理器registerBeanPostProcessors(beanFactory);beanPostProcess.end();// 7. 初始化MessageSource工作 包括:国际化,消息绑定,消息解析等。initMessageSource();// 8. 初始化事件派发器initApplicationEventMulticaster();// 9. 主要初始化特定上下文子类中的其他特殊 bean。onRefresh();// 10.将所有的监听器注册到容器中registerListeners();// 11.实例化所有的单实例beanfinishBeanFactoryInitialization(beanFactory);// 最后一步:完成容器的刷新工作 发布相应的事件。 finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// 如果抛出异常,则销毁已经创建的单例以节约资源。destroyBeans();// 重写设置激活状态cancelRefresh(ex);// 将异常抛出,传播给调用者。throw ex;}finally {// 重置 Spring 核心缓存// might not ever need metadata for singleton beans anymore...resetCommonCaches();contextRefresh.end();}}}
  1. prepareRefresh()Bean工厂创建前的前置处理

            this.startupDate = System.currentTimeMillis(); //记录启动时间this.closed.set(false); //是否关闭this.active.set(true); //是否激活if (this.logger.isDebugEnabled()) {if (this.logger.isTraceEnabled()) {this.logger.trace("Refreshing " + this);} else {this.logger.debug("Refreshing " + this.getDisplayName());}}this.initPropertySources(); //初始化一些属性设置 空方法 子类实现之后 自定义个性化属性this.getEnvironment().validateRequiredProperties(); //对自定义的属性进行合法校验if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);} else {this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}this.earlyApplicationEvents = new LinkedHashSet(); //保存容器中的事件,在合适的时机进行派发。}
    
  2. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 获取Bean工厂

  3. prepareBeanFactory(beanFactory); 对bean工厂进行预准备工作

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.beanFactory.setBeanClassLoader(getClassLoader()); //设置类加载器if (!shouldIgnoreSpel) {beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));}beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //设置支持的表达式解析器// 设置忽略的自动装配接口beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));......beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);////注册可以解析的自动装配 XXXAware接口相关  包括BeanFactory,ResourceLoader,ResourceLoader,ApplicationContext等。......// 添加后置处理器beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));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()));}// 注册环境变量等信息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 容器初始化之后的后置处理器 空方法 主要用于子类实现之后注册一些必备的组件

  5. invokeBeanFactoryPostProcessors Bean工厂的后置处理器 bean工厂标准初始化之后进行执行

    public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {Set<String> processedBeans = new HashSet<String>();if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);}else {regularPostProcessors.add(postProcessor);}}List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();//首先,调用实现 PriorityOrdered接口的bean注册前的前置处理器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);// 按照排好的顺序执行bean注册前的前置处理器registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();//然后,调用实现 Ordered接口的bean注册前的前置处理器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);// 按照排好的顺序执行bean的前置处理器registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// 执行其他的bean注册前的前置处理器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();}// 现在,调用到目前为止处理的所有处理器的 postProcessBeanFactory 回调。invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}//获取所有的BeanFactoryPostProcessor String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);//将实现不同接口的放入不同的集合中List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();List<String> orderedPostProcessorNames = new ArrayList<String>();List<String> nonOrderedPostProcessorNames = new ArrayList<String>();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);}}// 首先执行实现了priorityOrdered接口的beanFactoryProcessorsortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);//  然后执行实现Ordere接口d的beanFactoryProcessorList<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// 最后执行其他的beanFactoryProcessorList<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);//清空缓存beanFactory.clearMetadataCache();}
    
  6. 组件注册的后置处理器 registerBeanPostProcessors(beanFactory); 拦截Bean的创建过程

    public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {//获取容器中所有的postProcessorNamesString[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;// 加入自己的后置处理器beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));//分离实现 PriorityOrdered接口的Bean 的 BeanPostProcessor接口的BeanList<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();// 循环所有的后置处理器 通过MergedBeanDefinitionPostProcessor接口和Ordered接口进行优先级排序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);}}// 首先,注册实现 PriorityOrdered接口 的Bean和实现 BeanPostProcessors接口的Bean。sortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);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);}}//接下来,注册实现 Ordered 的 BeanPostProcessors。sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, orderedPostProcessors);// 现在,注册所有常规 BeanPostProcessor。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);// 最后,重新注册所有内部 BeanPostProcessor。sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);// 将用于检测内部 bean 的后处理器重新注册为 ApplicationListeners,// 将其移动到处理器链的末端(用于获取代理等)。beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}
    
  7. initMessageSource 初始化MessageSource 包括消息绑定,消息解析等

    protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();//如果容器中有messageSource组件 则赋值给自己的属性if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;if (hms.getParentMessageSource() == null) {hms.setParentMessageSource(getInternalParentMessageSource());}}if (logger.isDebugEnabled()) {logger.debug("Using MessageSource [" + this.messageSource + "]");}}else {// 如果没有 创建一个默认的DelegatingMessageSourceDelegatingMessageSource dms = new DelegatingMessageSource();dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);if (logger.isDebugEnabled()) {logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +"': using default [" + this.messageSource + "]");}}}
    
  8. initApplicationEventMulticaster 初始化事件派发器

    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.isDebugEnabled()) {logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");}}else {//如果容器中不存在,则创建默认的SimpleApplicationEventMulticasterthis.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);//注册到容器中beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);if (logger.isDebugEnabled()) {logger.debug("Unable to locate ApplicationEventMulticaster with name '" +APPLICATION_EVENT_MULTICASTER_BEAN_NAME +"': using default [" + this.applicationEventMulticaster + "]");}}}
    
  9. onRefresh 初始化剩下的bean 空方法,留给子类实现。

  10. registerListeners 注册监听器到容器中

    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);}}}
    
  11. finishBeanFactoryInitialization 实例化所有的单实例bean

    @Overridepublic void preInstantiateSingletons() throws BeansException {if (this.logger.isDebugEnabled()) {this.logger.debug("Pre-instantiating singletons in " + this);}//1. 获取容器中所有的bean的名字List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);// 2. 循环将bean进行初始化for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);//当bean不是抽象类,是单例,不是懒加载的时候,进行初始化if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//开始实例化if (isFactoryBean(beanName)) {final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);boolean isEagerInit;//如果当前bean是工厂bean 则调用ban自己重写的getObject方法创建组件 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {@Overridepublic Boolean run() {return ((SmartFactoryBean<?>) factory).isEagerInit();}}, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}else {//如果不是工厂bean 则使用此方法实例化beangetBean(beanName);}}}for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {smartSingleton.afterSingletonsInstantiated();return null;}}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}}
    

    上边代码的getBean方法

    protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {final String beanName = transformedBeanName(name);Object bean;// 先从缓存中获取Object sharedInstance = getSingleton(beanName);//如果缓存中有 if (sharedInstance != null && args == null) {if (logger.isDebugEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.debug("Returning cached instance of singleton bean '" + beanName + "'");}}//将缓存中的bean保存起来bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}//如果缓存中没有 则创建beanelse {if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}//判断是否有父工厂BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.String nameToLookup = originalBeanName(name);if (args != null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);}else {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}}if (!typeCheckOnly) {//标记当前bean背创建  多线程下的安全问题markBeanAsCreated(beanName);}try {//获取bean的定义信息final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);//获取当前bean的其他依赖beanString[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}registerDependentBean(dep, beanName);//循环获取依赖的beangetBean(dep);}}// 如果是单实例beanif (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {try {//实例化bean并返回return createBean(beanName, mbd, args);}catch (BeansException ex) {destroySingleton(beanName);throw ex;}}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {String scopeName = mbd.getScope();final Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new BeanCreationException(beanName,"Scope '" + scopeName + "' is not active for the current thread; consider " +"defining a scoped proxy for this bean if you intend to refer to it from a singleton",ex);}}}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}}if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {try {return getTypeConverter().convertIfNecessary(bean, requiredType);}catch (TypeMismatchException ex) {if (logger.isDebugEnabled()) {logger.debug("Failed to convert bean '" + name + "' to required type '" +ClassUtils.getQualifiedName(requiredType) + "'", ex);}throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}}return (T) bean;}
    
  12. finishRefresh 刷新容器 发布相应的事件

    protected void finishRefresh() {// 清除上下文级资源缓存clearResourceCaches();//初始化和生命周期有关的后置处理器。initLifecycleProcessor();getLifecycleProcessor().onRefresh();//发布最终事件。publishEvent(new ContextRefreshedEvent(this));if (!NativeDetector.inNativeImage()) {LiveBeansView.registerApplicationContext(this);}}
    

总结

  1. Spirng容器启动的时候,首先保存所有已经注册的bean的定义信息

    1. 通过XML,或者注解定义bean的信息。
  2. 容器会在合适的时机创建bean。

    1. 单例模式,会在启动容器的时候,统一循环创建。
    2. 非单例模式时,在用到bean的时候,利用getBean创建,并保存在容器中
  3. 每一个Bean创建完成都会使用各种后置处理器来增强Bean的功能。

    • 比如AutowiredAnnotationBeanPostProcessorBean用来处理自动注入的功能。
    • 比如AnnotationAwareAspectJAutoProxyCreatorBean用来AOP切面功能。
    • ……
  4. 事件驱动模型

    1. ApplicationListener : 事件监听
    2. ApplicationEventMuiticaster: 事件派发

相关文章:

Spring-IOC源码解析

容器创建过程 Spring容器的refresh方法 public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh this.applicationStartup.start("spring.context.refresh");// 1. 进行创…...

不会做大数据实时计算?10年数据分析师整理,一文给出解决方案

本文分为四个章节介绍实时计算&#xff0c;第一节介绍实时计算出现的原因及概念&#xff1b;第二节介绍实时计算的应用场景&#xff1b;第三节介绍实时计算常见的架构&#xff1b;第四节是实时数仓解决方案。 一、实时计算 实时计算一般都是针对海量数据进行的&#xff0c;并…...

如何让你的 WebSocket 接口测试更高效?拯救你的接口测试工作

目录 引言 WebSocket介绍 HTTP与WebSocket的区别 WebSocket测试方法 使用在线工具 使用Postman 使用Jmeter 使用Python 结语 引言 你是否曾经为 WebSocket 接口测试中复杂的协议和难以捕获的数据而感到束手无策&#xff1f;WebSocket 协议与传统的 HTTP 协议不同&…...

浅谈Linux 文件系统层次结构的组织方式

Linux 文件系统层次结构&#xff08;Filesystem Hierarchy Standard&#xff0c;简称 FHS&#xff09;是一种用于组织和管理 Linux 文件系统的标准化方式。该标准规定了 Linux 文件系统中各个目录和文件的组织方式、用途和权限&#xff0c;以提高文件系统的可读性、可维护性和可…...

创新案例 |探索 Tive 80% 的收入增长得益于智能物流服务、跟踪和实时可视化

您正在寻找可靠的物流解决方案吗&#xff1f; Tive 是领先的智能物流服务提供商&#xff0c;提供跟踪和实时可见性解决方案。使用 Tive&#xff0c;您可以主动监控公路、空运、海运和铁路运输。它可以帮助您减少运输问题并确保准时和全面交付&#xff0c;从而改善客户体验。 …...

makefile和cmake

Makefile 是一种文件&#xff0c;它定义了一个项目中的编译规则、依赖关系和构建过程。Makefile 可以自动化地构建和管理项目&#xff0c;使得整个项目的构建过程更加高效和可靠。下面是 Makefile 的常用语法&#xff1a; 1. 定义变量 变量可以用来保存一些常用的参数和路径&…...

通过OpenCL内核代码猜测设备寄存器个数

在OpenCL标准中&#xff0c;没有给出查看计算设备一共有多少寄存器&#xff0c;至少能分配给每个work-item多少寄存器使用的特征查询。而由于一个段内核代码是否因寄存器紧缺而导致性能严重下降也是一个比较重要的因素&#xff0c;因此我这边提供一个比较基本的方法来猜测当前计…...

C# + .Net6 实现TensorFlow图片分类

微软官网上发现一篇很有意思的文档&#xff1a;教程&#xff1a;用于对图像进行分类的 ML.NET 分类模型 - ML.NET | Microsoft Learn 这篇教程写的很学院派&#xff0c;但有点碎&#xff0c;属于上课不能打一秒钟瞌睡的那种。好在还是给出了完整的代码&#xff1a;samples/Pro…...

Ngnix负载均衡和高可用集群及搭建与相关理论

Ngnix负载均衡和高可用集群及搭建与相关理论 全文目录 Ngnix负载均衡和高可用集群及搭建与相关理论高可能保持原理配置 keepalived&#xff1a;配置keepalived的IP将外部域名解析到Keepalived的虚拟IP上如何验证配置的正确性Nginx专用调试工具ngx_conf_t如何对前后端多台服务器…...

2022年宜昌市网络搭建与应用竞赛样题(三)

网络搭建与应用竞赛样题&#xff08;三&#xff09; 技能要求 &#xff08;总分1000分&#xff09; 竞赛说明 一、竞赛内容分布 “网络搭建与应用”竞赛共分三个部分&#xff0c;其中&#xff1a; 第一部分&#xff1a;网络搭建及安全部署项目&#xff08;500分&#xff0…...

为什么PCB设计完成后需要放置mark点

PCB设计中的Mark点是指一些标记点&#xff0c;通常用于促进PCB制造和组装过程中的准确性和一致性。这些标记点在制造过程中可以帮助操作员进行自动化定位&#xff0c;从而确保所有部件都被正确组装到其正确位置&#xff0c;这对于确保产品的质量和可靠性至关重要。 下面&#…...

代理IP:IP代理技术与Socks5协议

代理IP是一种用于隐藏真实IP地址的技术&#xff0c;它可以将请求发送至代理服务器&#xff0c;再由代理服务器转发请求至目标网站。代理服务器会在请求过程中替换真实IP地址&#xff0c;从而保护用户的隐私和安全。在网络爬虫、反爬虫、匿名访问等场景中&#xff0c;代理IP技术…...

如何让java程序员生涯更顺利?我聊聊提升技术水平的五个方面

今天我想和大家聊聊程序员职业发展的问题。相信大家都知道&#xff0c;IT公司因为各种原因裁员&#xff0c;对程序员的前途发展都是不利的。特别是等到你30多岁&#xff0c;上有老下有小&#xff0c;仍然要加班&#xff0c;与年轻人竞争体力和智力&#xff0c;这是很艰难的。如…...

快速排序、希尔排序、归并排序、堆排序、插入排序、冒泡排序、选择排序(递归、非递归)C语言详解

1.排序的概念及其运用 1.1排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&a…...

ChatGPT一键私有部署,全网可用,让访问、问答不再受限,且安全稳定!

前言 ChatGPT由于在访问上有一些限制&#xff0c;使用并不便利。目前国内可以直接访问的大部分是调用API返回结果&#xff0c;我们去使用时总会有次数限制&#xff0c;而且它们可能随便崩掉。 其实&#xff0c;目前我们访问过的大部分国内的网页包括UI&#xff0c;其实是套用了…...

自学黑客(网络安全),一般人我劝你还是算了吧

一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员&#xff08;以编程为基础的学习&#xff09;再开始学习 我在之前的回答中&#xff0c;我都一再强调不要以编程为基础再开始学习网络安全&#xff0c;一般来说&#xff0c;学习编程不但学习周期长&#xff0c;而…...

盘“底座”,盘出新生意经

本文转自首席信息官 作者 徐蕊 导读 卖“底座”&#xff0c;这是一门新的生意&#xff0c;也是用友与友商差异化的商业竞争优势所在。 大型企业都在建“数智化底座” 有这样两类企业&#xff0c;他们截然不同&#xff0c;但在数智化的建设上殊途同归。 随着中国经济的发展&a…...

《花雕学AI》Poe:一个让你和 AI 成为朋友的平台,带你探索 ChatGPT4 和其他 八种AI 模型的奥秘

你是否曾经梦想过&#xff0c;能够在一个平台上&#xff0c;和多种不同的 AI 模型进行有趣、有用、有深度的对话&#xff0c;甚至还能轻松地把你的对话分享给其他人&#xff1f;如果你有这样的梦想&#xff0c;那么 Poe 一站式 AI 工具箱就是你的不二之选&#xff01; Poe 是国…...

单片机GD32F303RCT6 (Macos环境)开发 (十五)—— i2c1采用DMA方式的读写函数

i2c1采用DMA方式的读写函数 1、关于i2c1的DMA的映射如图 2、关于代码的宏定义配置 Application目录的Makefile中 ENABLE_I2C_TEST yes才会编译I2C1的相关代码。 同时修改i2c.h文件&#xff0c;定义I2C1_MODE为I2C1_MODE_DMA&#xff0c;这样i2c1的配置为dma模式。 #define …...

通知短信 API 技术细节以及发送流程机制原理解析

引言 短信是一种简单、直接、高效的通信方式&#xff0c;被广泛应用于各个领域。在移动互联网时代&#xff0c;短信成为了客户服务、政府通知、公共服务等方面的重要工具。为了更好地利用短信这种通信方式&#xff0c;通知短信 API应运而生。短信API可以帮助企业、政府和应用程…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...