手写Spring高级源码(五): Spring IOC源码深度剖析

spring高级源码笔记:深入理解阿里spring源码核心思想及框架应用 一,spring概述 Spring 简介 Spring 是分层的 full-stack(全栈) 轻量级开源框架,以 IoC 和 AOP 为内核,提供了展现层 SpringMVC 和业务层事务管理等众多的企业级应⽤技术,还能整合开源世界众多著名的第三⽅框架和类库,已经成为使⽤最多的 Java EE 企业应⽤开源框架。 我们经常说的 Spring 其实指的是Spring Framework(spring 框架)。 本篇文章主要内容会有Spring 概述(基本情况),核⼼思想 IoC 和 AOP, 阅读详情

第五部分 Spring IOC源码深度剖析

 
1. 好处:提⾼培养代码架构思维、深⼊理解框架
2. 原则
  • 定焦原则:抓主线
  • 宏观原则:站在上帝视⻆,关注源码结构和业务流程(淡化具体某⾏代码的编写细节)
3. 读源码的⽅法和技巧
  • 断点(观察调⽤栈)
  • 反调(Find Usages)
  • 经验(spring框架中doXXX,做具体处理的地⽅)
4. Spring 源码构建
  • 下载源码(github)
  • 安装gradle 5.6.3(类似于maven) Idea 2019.1 Jdk 11.0.5
  • 导⼊(耗费⼀定时间)
  • 编译⼯程(顺序:core-oxm-context-beans-aspects-aop)⼯程—>tasks—>compileTestJava

第1节 Spring IoC容器初始化主体流程

1.1 Spring IoC的容器体系

IoC 容器是 Spring 的核⼼模块,是抽象了对象管理、依赖关系管理的框架解决⽅案。 Spring 提供了很多的容器,其中 BeanFactory 是顶层容器(根容器),不能被实例化,它定义了所有 IoC 容器 必须遵从 的⼀套原则,具体的容器实现可以增加额外的功能,⽐如我们常⽤到的ApplicationContext ,其下更具 体的实现如 ClassPathXmlApplicationContext 包含了解析 xml 等⼀系列的内容,AnnotationConfifigApplicationContext 则是包含了注解解析等⼀系列的内容。 Spring IoC 容器继承体系⾮常聪明,需要使⽤哪个层次⽤哪个层次即可,不必使⽤功能⼤⽽全的。
 
BeanFactory 顶级接⼝⽅法栈如下
 
 
BeanFactory 容器继承体系
 
 
通过其接⼝设计,我们可以看到我们⼀贯使⽤的 ApplicationContext 除了继承 BeanFactory 的⼦接⼝, 还继承了ResourceLoader 、 MessageSource 等接⼝,因此其提供的功能也就更丰富了。下⾯我们以 ClasspathXmlApplicationContext 为例,深⼊源码说明 IoC 容器的初始化流程。

 

 

1.2 Bean⽣命周期关键时机点

思路: 创建⼀个类 LagouBean ,让其实现⼏个特殊的接⼝,并分别在接⼝实现的构造器、接⼝⽅法中断点,观察线程调⽤栈,分析出 Bean 对象创建和管理关键点的触发时机
 
LagouBean类
 
package com.lagou;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* @Author 应癫
* @create 2019/12/3 11:46
*/
public class LagouBean implements InitializingBean{
 /**
 * 构造函数
 */
 public LagouBean(){
 System.out.println("LagouBean 构造器...");
 }
 /**
 * InitializingBean 接⼝实现
 */
 public void afterPropertiesSet() throws Exception {
 System.out.println("LagouBean afterPropertiesSet...");
 } }
BeanPostProcessor 接⼝实现类
 
 
package com.lagou;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* @Author 应癫
* @create 2019/12/3 16:59
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
 public MyBeanPostProcessor() {
 System.out.println("BeanPostProcessor 实现类构造函数...");
 }
 @Override
 public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
 if("lagouBean".equals(beanName)) {
 System.out.println("BeanPostProcessor 实现类
postProcessBeforeInitialization ⽅法被调⽤中......");
 }
 return bean;
 }
 @Override
 public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
 if("lagouBean".equals(beanName)) {
 System.out.println("BeanPostProcessor 实现类
postProcessAfterInitialization ⽅法被调⽤中......");
 }
 return bean;
 } }

BeanFactoryPostProcessor 接⼝实现类

package com.lagou;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* @Author 应癫
* @create 2019/12/3 16:56
*/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
 public MyBeanFactoryPostProcessor() {
 System.out.println("BeanFactoryPostProcessor的实现类构造函数...");
 }
 @Override
 public void postProcessBeanFactory(ConfigurableListableBeanFactory
beanFactory) throws BeansException {
 System.out.println("BeanFactoryPostProcessor的实现⽅法调⽤中......");
 } }
IoC 容器源码分析⽤例
/**
* Ioc 容器源码分析基础案例
*/
@Test
public void testIoC() {
 ApplicationContext applicationContext = new 
ClassPathXmlApplicationContext("classpath:applicationContext.xml");
 LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
 System.out.println(lagouBean);
}
( 1 )分析 Bean 的创建是在容器初始化时还是在 getBean 时

 

根据断点调试,我们发现,在未设置延迟加载的前提下, Bean 的创建是在容器初始化过程中完成的。
 
( 2 )分析构造函数调⽤情况

通过如上观察,我们发现构造函数的调⽤时机在 AbstractApplicationContext 类 refresh ⽅法的fifinishBeanFactoryInitialization(beanFactory)处 ;
( 3 )分析 InitializingBean 之 afterPropertiesSet 初始化⽅法调⽤情况

观察调⽤栈

通过如上观察,我们发现 InitializingBean 中 afterPropertiesSet ⽅法的调⽤时机也是在 AbstractApplicationContext类 refresh ⽅法的 fifinishBeanFactoryInitialization(beanFactory);
( 4 )分析 BeanFactoryPostProcessor 初始化和调⽤情况
分别在构造函数、 postProcessBeanFactory ⽅法处打断点,观察调⽤栈,发现 BeanFactoryPostProcessor 初始化 在 AbstractApplicationContext 类 refresh ⽅法的invokeBeanFactoryPostProcessors(beanFactory);
postProcessBeanFactory 调⽤ 在 AbstractApplicationContext 类 refresh ⽅法的
invokeBeanFactoryPostProcessors(beanFactory);
( 5 )分析 BeanPostProcessor 初始化和调⽤情况
分别在构造函数、 postProcessBeanFactory ⽅法处打断点,观察调⽤栈,发现 BeanPostProcessor 初始化 在 AbstractApplicationContext 类 refresh ⽅法的 registerBeanPostProcessors(beanFactory);
postProcessBeforeInitialization 调⽤ 在 AbstractApplicationContext 类 refresh ⽅法的 fifinishBeanFactoryInitialization(beanFactory);
postProcessAfterInitialization 调⽤ 在 AbstractApplicationContext 类 refresh ⽅法的
fifinishBeanFactoryInitialization(beanFactory);
( 6 )总结
根据上⾯的调试分析,我们发现 Bean 对象创建的⼏个关键时机点代码层级的调⽤都在
AbstractApplicationContext 类 的 refresh ⽅法中,可⻅这个⽅法对于 Spring IoC 容器初始化来说相当
关键,汇总如下:

1.3 Spring IoC 容器初始化主流程
由上分析可知, Spring IoC 容器初始化的关键环节就在 AbstractApplicationContext#refresh() ⽅法中 ,我们查看 refresh ⽅法来俯瞰容器创建的主体流程,主体流程下的具体⼦流程我们后⾯再来讨论。
@Override
public void refresh() throws BeansException, IllegalStateException {
 synchronized (this.startupShutdownMonitor) {
 // 第⼀步:刷新前的预处理
 prepareRefresh();
 /*
 第⼆步:
 获取BeanFactory;默认实现是DefaultListableBeanFactory
 加载BeanDefition 并注册到 BeanDefitionRegistry
 */
 ConfigurableListableBeanFactory beanFactory =
obtainFreshBeanFactory();
 // 第三步:BeanFactory的预准备⼯作(BeanFactory进⾏⼀些设置,⽐如context的类加
载器等)
 prepareBeanFactory(beanFactory);
 try {
 // 第四步:BeanFactory准备⼯作完成后进⾏的后置处理⼯作
 postProcessBeanFactory(beanFactory);
 // 第五步:实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean
 invokeBeanFactoryPostProcessors(beanFactory);
 // 第六步:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执
⾏
 registerBeanPostProcessors(beanFactory);
 // 第七步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
 initMessageSource();
 // 第⼋步:初始化事件派发器
 initApplicationEventMulticaster();
 // 第九步:⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑
 onRefresh();
 // 第⼗步:注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器
bean
 registerListeners();
 /*
 第⼗⼀步:
 初始化所有剩下的⾮懒加载的单例bean
 初始化创建⾮懒加载⽅式的单例Bean实例(未设置属性)
 填充属性
 初始化⽅法调⽤(⽐如调⽤afterPropertiesSet⽅法、init-method⽅法)
 调⽤BeanPostProcessor(后置处理器)对实例bean进⾏后置处
 */
 finishBeanFactoryInitialization(beanFactory);
 /*
 第⼗⼆步:
 完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事
件 (ContextRefreshedEvent)
 */
 finishRefresh();
 }
第2节 BeanFactory创建流程
2.1 获取BeanFactory⼦流程
时序图如下
2.2 BeanDefinition加载解析及注册⼦流程
(1)该⼦流程涉及到如下⼏个关键步骤
Resource定位:指对BeanDefinition的资源定位过程。通俗讲就是找到定义Javabean信息的XML⽂
件,并将其封装成Resource对象。
BeanDefinition载⼊ :把⽤户定义好的Javabean表示为IoC容器内部的数据结构,这个容器内部的数
据结构就是BeanDefinition。
注册BeanDefinition到 IoC 容器
(2)过程分析
 ......
 }
}

第2节 BeanFactory创建流程

2.1 获取BeanFactory⼦流程

时序图如下

2.2 BeanDefifinition加载解析及注册⼦流程

( 1 )该⼦流程涉及到如下⼏个关键步骤
Resource 定位: 指对 BeanDefifinition 的资源定位过程。通俗讲就是找到定义 Javabean 信息的 XML ⽂件,并将其封装成Resource 对象。
BeanDefifinition 载⼊ :把⽤户定义好的 Javabean 表示为 IoC 容器内部的数据结构,这个容器内部的数据结构就是BeanDefifinition 。
注册 BeanDefifinition 到 IoC 容器
( 2 )过程分析
Step 1 : ⼦流程⼊⼝在 AbstractRefreshableApplicationContext#refreshBeanFactory ⽅法中

Step 2 : 依次调⽤多个类的 loadBeanDefifinitions ⽅法 —> AbstractXmlApplicationContext —> AbstractBeanDefifinitionReader —> XmlBeanDefifinitionReader ⼀直执⾏到XmlBeanDefifinitionReader 的 doLoadBeanDefifinitions ⽅法

Step 3 : 我们重点观察 XmlBeanDefifinitionReader 类的 registerBeanDefifinitions ⽅法,期间产⽣了多次重载调⽤,我们定位到最后⼀个

此处我们关注两个地⽅:⼀个 createRederContext ⽅法,⼀个是DefaultBeanDefifinitionDocumentReader类的 registerBeanDefifinitions ⽅法,先进⼊createRederContext ⽅法看看

我们可以看到,此处 Spring ⾸先完成了 NamespaceHandlerResolver 的初始化。
我们再进⼊ registerBeanDefifinitions ⽅法中追踪,调⽤了
DefaultBeanDefifinitionDocumentReader#registerBeanDefifinitions ⽅法

进⼊ parseBeanDefifinitions ⽅法

进⼊ parseDefaultElement ⽅法
 
进⼊ processBeanDefifinition ⽅法
 
 
 
⾄此,注册流程结束,我们发现,所谓的注册就是把封装的 XML 中定义的 Bean 信息封装为 BeanDefifinition 对象之后放⼊⼀个 Map 中, BeanFactory 是以 Map 的结构组织这些 BeanDefifinition 的。
 
 
可以在 DefaultListableBeanFactory 中看到此 Map 的定义
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new
ConcurrentHashMap<>(256);
( 3 )时序图
 
 

第3节 Bean创建流程

  • 通过最开始的关键时机点分析,我们知道Bean创建⼦流程⼊⼝在AbstractApplicationContext#refresh()⽅法的fifinishBeanFactoryInitialization(beanFactory) 处
  • 进⼊fifinishBeanFactoryInitialization
 
 
继续进⼊ DefaultListableBeanFactory 类的 preInstantiateSingletons ⽅法,我们找到下⾯部分的代码,看到⼯⼚Bean 或者普通 Bean ,最终都是通过 getBean 的⽅法获取实例
 
 
 
  • 继续跟踪下去,我们进⼊到了AbstractBeanFactory类的doGetBean⽅法,这个⽅法中的代码很多,我们直接找到核⼼部分
 
 
  • 接着进⼊到AbstractAutowireCapableBeanFactory类的⽅法,找到以下代码部分
 
  • 进⼊doCreateBean⽅法看看,该⽅法我们关注两块重点区域
创建 Bean 实例,此时尚未设置属性
 
 
 
 
  • lazy-init 延迟加载机制分析
 
普通 Bean 的初始化是在容器启动初始化阶段执⾏的,⽽被 lazy-init=true 修饰的 bean 则是在从容器⾥第⼀次进⾏context.getBean() 时进⾏触发。 Spring 启动的时候会把所有 bean 信息 ( 包括 XML 和注解 ) 解 析转化成Spring 能够识别的 BeanDefifinition 并存到 Hashmap ⾥供下⾯的初始化时⽤,然后对每个 BeanDefifinition 进⾏处理,如果是懒加载的则在容器初始化阶段不处理,其他的则在容器初始化阶段进⾏初始化并依赖注⼊
public void preInstantiateSingletons() throws BeansException {
 // 所有beanDefinition集合
 List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
 // 触发所有⾮懒加载单例bean的初始化
 for (String beanName : beanNames) {
 // 获取bean 定义
 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
 // 判断是否是懒加载单例bean,如果是单例的并且不是懒加载的则在容器创建时初始化
 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
 // 判断是否是 FactoryBean
 if (isFactoryBean(beanName)) {
 final FactoryBean<?> factory = (FactoryBean<?>)
getBean(FACTORY_BEAN_PREFIX + beanName);
 boolean isEagerInit;
 if (System.getSecurityManager() != null && factory instanceof
SmartFactoryBean) {
 isEagerInit = AccessController.doPrivileged(new
PrivilegedAction<Boolean>() {
 @Override
 public Boolean run() {
 return ((SmartFactoryBean<?>) factory).isEagerInit();
 }
 }, getAccessControlContext());
 }
 }else {
 /*
 如果是普通bean则进⾏初始化并依赖注⼊,此 getBean(beanName)接下来触发的逻辑
和
 懒加载时 context.getBean("beanName") 所触发的逻辑是⼀样的
 */
 getBean(beanName);
 }
 }
 }
}
  • 总结
  • 对于被修饰为lazy-init的bean Spring 容器初始化阶段不会进⾏ init 并且依赖注⼊,当第⼀次 进⾏getBean时候才进⾏初始化并依赖注⼊
  • 对于⾮懒加载的bean,getBean的时候会从缓存⾥头获取,因为容器初始化阶段 Bean 已经 初始化完成并缓存了起来
 

5.1 什么是循环依赖

循环依赖其实就是循环引⽤,也就是两个或者两个以上的 Bean 互相持有对⽅,最终形成闭环。⽐如 A 依赖于B , B 依赖于 C , C ⼜依赖于 A 。
 
 
 
注意,这⾥不是函数的循环调⽤,是对象的相互依赖关系。循环调⽤其实就是⼀个死循环,除⾮有终结条件。
Spring 中循环依赖场景有:
  • 构造器的循环依赖(构造器注⼊)
  • Field 属性的循环依赖(set注⼊)
其中,构造器的循环依赖问题⽆法解决,只能拋出 BeanCurrentlyInCreationException 异常,在解决属性循环依赖时,spring 采⽤的是提前暴露对象的⽅法。
 
 

5.2 循环依赖处理机制

  • 单例 bean 构造器参数循环依赖(⽆法解决)
  • prototype 原型 bean循环依赖(⽆法解决)
对于原型 bean 的初始化过程中不论是通过构造器参数循环依赖还是通过 setXxx ⽅法产⽣循环依赖,Spring 都 会直接报错处理。
 
AbstractBeanFactory.doGetBean() ⽅法:
 
if (isPrototypeCurrentlyInCreation(beanName)) {
 throw new BeanCurrentlyInCreationException(beanName);
}
protected boolean isPrototypeCurrentlyInCreation(String beanName) {
 Object curVal = this.prototypesCurrentlyInCreation.get();
 return (curVal != null &&
 (curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>)
curVal).contains(beanName))));
}
在获取 bean 之前如果这个原型 bean 正在被创建则直接抛出异常。原型 bean 在创建之前会进⾏标记这个beanName 正在被创建,等创建结束之后会删除标记
 
try {
 //创建原型bean之前添加标记
 beforePrototypeCreation(beanName);
 //创建原型bean
 prototypeInstance = createBean(beanName, mbd, args);
}
finally {
 //创建原型bean之后删除标记
 afterPrototypeCreation(beanName);
}
总结: Spring 不⽀持原型 bean 的循环依赖。
 
  • 单例bean通过setXxx或者@Autowired进⾏循环依赖
Spring 的循环依赖的理论依据基于 Java 的引⽤传递,当获得对象的引⽤时,对象的属性是可以延后设置的,但是构造器必须是在获取引⽤之前Spring通过 setXxx 或者 @Autowired ⽅法解决循环依赖其实是通过提前暴露⼀个 ObjectFactory 对象来完成的,简单来说ClassA 在调⽤构造器完成对象初始化之后,在调⽤ ClassA 的 setClassB ⽅法之前就把ClassA 实例化的对象通过 ObjectFactory 提前暴露到 Spring 容器中。
 
Spring 容器初始化 ClassA 通过构造器初始化对象后提前暴露到 Spring 容器。
boolean earlySingletonExposure = (mbd.isSingleton() &&
this.allowCircularReferences &&
 isSingletonCurrentlyInCreation(beanName));
 if (earlySingletonExposure) {
 if (logger.isDebugEnabled()) {
 logger.debug("Eagerly caching bean '" + beanName +
 "' to allow for resolving potential circular references");
 }
 //将初始化后的对象提前已ObjectFactory对象注⼊到容器中
 addSingletonFactory(beanName, new ObjectFactory<Object>() {
 @Override
 public Object getObject() throws BeansException {
 return getEarlyBeanReference(beanName, mbd, bean);
 }
 });
 }
ClassA 调⽤ setClassB ⽅法, Spring ⾸先尝试从容器中获取 ClassB ,此时 ClassB 不存在 Spring 容器中。
Spring 容器初始化 ClassB ,同时也会将 ClassB 提前暴露到 Spring 容器中ClassB调⽤ setClassA ⽅法, Spring 从容器中获取 ClassA ,因为第⼀步中已经提前暴露了ClassA,因此可以获取到 ClassA 实例ClassA通过 spring 容器获取到 ClassB ,完成了对象初始化操作。
这样 ClassA 和 ClassB 都完成了对象初始化操作,解决了循环依赖问题。
 
 

更多关于Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构面试解析等等可以去这个Github链接地址:

https://github.com/ThinkingHan/Java-note 阅读,Star一下吧,感谢支持~

 
Spring的IoC详解:从概念到源码的深度剖析 摘要: Spring IoC(控制反转)是Spring框架的核心,通过容器管理对象创建和依赖注入,实现了对象控制权的反转。文章详细解析了IoC的基本概念(包括DI依赖注入的三种方式)、Spring容器实现(BeanFactory与ApplicationContext)、初始化流程及源码分析,并深入探讨了依赖注入原理、Bean的生命周期阶段(从实例化到销毁)以及高级特性(作用域、自动装配、条件注解)。最后提供了最佳实践建议,如构造器注入优先用于强制依赖。本文为开发者全面理解Spring IoC提供了系统性指导 阅读详情

相关推荐

我的架构梦:(五)Spring框架中的IoC容器源码分析(上)

一、Spring IoC基础 1、bean与BeanFactory的关系 2、BeanFactory与ApplicationContext区别 BeanFactory是Spring框架中IoC容器的顶层接口,它只是用来定义一些基础功能,定义一些基础规范,而 ApplicationContext是它的一个子接口,所以ApplicationContext是具备BeanFactory提供的全部功能的。 通常,我们称BeanFactory为Spring IoC的基础容器,ApplicationContext是容器

riemann_的博客 945

spring ioc源码详解

ioc是 spring 中最最最最重要的部分,本文将会详细讲解 ioc的源码。

修理男爵的博客 3357

STM32F103C8T6驱动DM542步进电机:从CubeMX配置到按键控制的全流程避坑指南

本文详细介绍了如何使用STM32F103C8T6通过CubeMX配置驱动DM542步进电机的全流程,包括PWM频率计算、GPIO模式选择及按键控制实现。重点解决了常见硬件连接错误、PWM参数配置及加减速算法优化,帮助开发者快速搭建稳定的电机控制系统。

weixin_42741930的博客 308

The method‘s class, org.springframework.beans.factory.config.ConfigurableListableBeanFactory,

前言 The method's class, org.springframework.beans.factory.config.ConfigurableListableBeanFactory, is available from the following locations: jar:file:/D:/work/Mavenrepo/org/springframework/spring-beans/5.1.8.RELEASE/spring-beans-5.1.8.RELEASE.jar!/or...

道阻且长,行则将至 行而不辍,未来可期 3393

机械臂速成小指南(七):从旋转矩阵到齐次变换——机械臂位姿的数学表达

本文详细介绍了机械臂位姿描述的数学基础,包括旋转矩阵、欧拉角和齐次变换等核心概念。通过解析旋转矩阵的几何意义和合成方法,以及欧拉角的直观描述,帮助读者理解机械臂位姿的数学表达。文章还探讨了齐次变换在工程实践中的应用,并提供了数值稳定性、坐标系约定和计算效率等实用建议。

cuda7parallel的博客 835

使用libx265对YUV进行h265编码

使用libx265对YUV进行h265编码

Embedded engineer 3079

Spring-ioc源码

);if (!Class

weixin_44175409的博客 484

深入解析PCIe Retimer:工作原理与典型应用场景

本文深入解析了PCIe Retimer的工作原理与核心价值。作为高速信号的中继再生器,Retimer通过时钟数据恢复和信号再生技术,有效解决长距离或复杂通道中的信号衰减与完整性问题,从而极大地扩展了PCIe链路的有效传输距离。文章详细阐述了其内部架构、自动与手动两种工作模式,并重点介绍了在长距离板间互连、复杂背板设计等典型应用场景中的关键作用。

weixin_29195615的博客 506

Spring的BeanFactory

BeanFactory BeanFactory 定义获取Bean以及Bean的各种属性,顶层接口 `` BeanFactory

liulong1010的专栏 633

阿里云一键登录Java后端实战:5分钟搞定号码认证服务集成(附完整代码)

本文详细介绍了如何在Java后端项目中快速集成阿里云号码认证服务(PNVS),实现高效、安全的一键登录功能。文章从核心架构、安全机制解析入手,提供了完整的Maven依赖配置、服务端环境准备、核心业务逻辑实现(包括Token验证、用户处理、异常降级)以及生产环境下的性能优化、监控与部署方案,并附有可直接使用的完整代码示例。

p1q2r的博客 845

程序员应用AI大模型创业实现财务自由的100种赚钱方案原理与实战指南

成功的 AI 创业者都遵循着 “技术 + 需求 + 变现” 的铁三角法则。记住:不是要做 “全能大模型”,而是成为某个垂直领域的 “AI 解决方案专家”。现在就开始行动:用周末 2 小时完成第一个 MVP,下周启动种子用户测试,三个月内找到可复制的盈利模式。当你实现第一个 10 万用户时,会发现财务自由的密码藏在持续迭代的每个 0.1 版本更新中。延伸思考:你的技术背景适合切入哪个细分领域?

AI天才研究院 1380

Spring IOC 的原理及源码

试想一下,如果一个系统有大量的组件,其生命周期和相互之间的依赖关系如果由组件自身来维护,也就是对各个类的控制权在我们手中,这样的话我们需要手动的去创建各个类并且维持他们的依赖关系,不但大大增加了系统的复杂度,而且会导致组件之间极为紧密的耦合

sekever的博客 1034

【精细解读】xapp585(多通道LVDS接口ADC)

xapp585的参考设计有Verilog和VHDL两种源码。

FPGA艺术家的博客 532

Spring 源码学习资料 从手写到源码深度剖析

通过这套 Spring 源码学习资料,大家可以从基础到高级,系统地学习 Spring 框架的核心技术和实现原理。无论是手写代码还是深入源码,这些资料都将帮助大家更好地理解和使用 Spring 框架,提升开发效率和代码质量。如果你对 Spring 源码感兴趣,或者想深入了解 Spring 框架的实现原理,这套资料绝对值得一学!希望这些资料能够帮助你在 Spring 学习的道路上更进一步。

运维老生常谈 3443

2023年下半年网络工程师案例分析真题答案解析

R1] ip route-static 0.0.0.0 0.0.0.0 GigabitEthemet2/0/1 (3) track (4) R1 to R2 //配置R1的缺省路由,联动BFD使得R1到2的流量优先走R1->S1->R2链路,当此链路发生故障时,流量切换到R1->R3->R2链路上。当同一VLAN内也需要网络隔离时,我们可采用交换机的(2)功能,若在配置了二层隔离后,部分主机有互通的需求,则可在需求主机的网关上配置(3)功能。不需要,MAC地址是数据链路层封装以太帧的地址标识。

鹿鸣天涯 751

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

吹爆!阿里新产Spring源码高级笔记,原来看懂源码如此简单

Spring的影响力想必无需与大家多说,如果你用spring,那么读读源码有助于对你最重要的工具的理解,好的框架源码也可以帮助我们理解什么是好代码。 刚参加工作那会,没想过去读源码,更没想过去改框架的源码;甚至觉得那些有事没事扯源码的人就是在装,只是为了提高他们的逼格而已,在工作中没什么太大的用;但现在我的想法改变了,下面我就我自己的一些见解来与大家聊聊为什么要读Spring源码。 为什么要读Spring源码? 说实话我读Spring源码一刚开始为了面试,后来为了解决工作中的问题,再后来就是个人喜好

Java圈全能架构师的博客 3591

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

阿里内部Spring源码教程笔记开源!Spring源码其实也可以这么简单

前言 Spring以loC和AOP为内核,提供了展现层SpringMVC和业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,已经成为使用最多的Java EE企业应用开源框架。那么这么6的一个框架其源码肯定有着多年积淀下来的精华,这些精华是非常值得我们学习的 而Java开发人员都知道,阅读源码是一个非常好的学习方式,在我们日常工作中或多或少都会接触一些开源代码。不管我们当前是什么水平,通过反复阅读源码能力肯定能有所提升,小到对源码所提供的功能上的使用更加熟练,大到使我们的程

Java圈全能架构师的博客 4130

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Spring IOC源码深度剖析

Spring IOC源码深度剖析 文章目录**Spring IOC**源码深度剖析1. 源码阅读方法2. **Spring IoC**容器初始化主体流程2.1 **Spring IoC**的容器体系**2.2 Bean**生命周期关键时机点**先说结论**详细分析2.3 **Spring IoC**容器初始化主流程3. **BeanFactory**创建流程3.1 获取**BeanFactory**子流程3.2 BeanDefinition加载解析及注册子流程4. **Bean**创建流程5. **laz

weixin_43871142的博客 603

源码>Spring IOC源码深度剖析!干货满满!干货到底!

今天带来Spring IOC源码深度剖析!喜欢的朋友们可以来个一键三连支持下博主哦~ 目录Spring IOC源码深度剖析第1节 Spring IoC容器初始化主体流程1.1 Spring IoC的容器体系1.2 Bean⽣命周期关键时机点1.3 Spring IoC容器初始化主流程第2节 BeanFactory创建流程2.1 获取BeanFactory⼦流程2.2 BeanDefinition加载解析及注册⼦流程第3节 Bean创建流程第4节 lazy-init 延迟加载机制原理第5节 Spring .

Java_Yhua的博客 612

spring框架高级编程 pdf_啃完这份宝藏级“Spring高级源码笔记”,面试P7问源码还会心虚?...

前言Spring是分层的full-stack(全栈)轻量级开源框架,以IOC和APO和内核,提供了展现层SpringMVC和业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,已经成为使用最多的JavaEE企业应用开源框架。而我们经常说的Spring其实指的是Spring Framework(Spring框架)。今天咱们来分享个《Spring高级源码笔记》,总共包含七...

weixin_39968861的博客 438

源码剖析_Spring源码高级笔记——Spring IOC源码深度剖析

Spring IOC源码深度剖析好处:提高培养代码架构思维、深入理解框架原则定焦原则︰抓主线宏观原则:站在上帝视角,关注源码结构和业务流程(淡化具体某行代码的编写细节)读源码的方法和技巧断点(观察调用栈)反调(Find Usages)经验(spring框架中doXXX,做具体处理的地方)Spring源码构建下载源码(github)安装gradle 5.6.3(类似于maven) ldea 2019...

weixin_39548193的博客 107

Spring进阶(二)IOC高级应用及源码深度剖析

一. Spring IOC基础知识 Spring核心之IOC--快速入门_舞鹤白沙编码日志-优快云博客 Spring核心之IOC--相关API_舞鹤白沙编码日志-优快云博客 Spring核心之IOC--配置文件开发_舞鹤白沙编码日志-优快云博客 Spring核心之IOC--注解开发_舞鹤白沙编码日志-优快云博客 (一)BeanFactory与ApplicationContext区别 BeanFactory是Spring框架中IoC容器的顶层接⼝,它只是⽤来定义⼀些基础功能...

舞鹤白沙编码日志 634

淦!Alibaba架构师《Spring IOC+AOP深度分析》笔记内容,看完犹如醍醐灌顶!

前言 Spring框架自诞生来就备受开发者青睐,很多开发者一致认为它是目前最屌的Java项目,正是因为它的“过人之处”,市面上99%的企业都在使用Spring框架。 所以,Spring一直Java技术里的重点难点,也是Java开发者面试中的重点,重要性不言而喻。 谷歌大牛甚至直言:“对于Java开发者,学习Java就是在学Spring。” 本篇内容一定是你从所未见过的学习笔记,我将分成4个部分跟大家分享,请认真看完本文,对你工作一定大有帮助! 本文所提供的限量版笔记无偿分享,请关注我!转发!点赞!

QAQFyl的博客 1117

啃完这份宝藏级“Spring高级源码笔记”,再也不怕面试官问Spring源码了

第1节 Spring简介第2节 Spring发展历程第3节 Spring的优势第4节 Spring的核心结构Spring的核心结构上⼀部分我们理解了 IoC 和 AOP 思想,我们先不考虑 Spring 是如何实现这两个思想的,此处准备了⼀个『银⾏转账』的案例,请分析该案例在代码层次有什么问题?分析之后使⽤我们已有知识解决这些问题(痛点)。其实这个过程我们就是在⼀步步分析并⼿写实现 IoC 和 AOP。第1节 银行转账案例界面第2节 银行转账案例表结构第3节 银行转账案例代码调用结构。

知识分享官 890

spring 源码_Spring源码高级笔记——Spring IOC源码深度剖析

Spring IOC源码深度剖析好处:提高培养代码架构思维、深入理解框架原则定焦原则︰抓主线宏观原则:站在上帝视角,关注源码结构和业务流程(淡化具体某行代码的编写细节)读源码的方法和技巧断点(观察调用栈)反调(Find Usages)经验(spring框架中doXXX,做具体处理的地方)Spring源码构建下载源码(github)安装gradle 5.6.3(类似于maven) ldea 2019...

weixin_39916379的博客 197
上一篇: 全网独家Spring/Cloud/MVC/Boot,脑图+面试+进阶,就问你服不服?
下一篇: 秋招预热,渣硕首站告捷,靠着数套的Java刷题PDF成功“混进”腾讯T3!
加班不秃顶
博客等级 码龄7年 1822粉丝 599原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值