尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Spring学习笔记(一):吃透IOC核心思想,小白从零入门

Spring学习笔记(一):吃透IOC核心思想,小白从零入门 Spring学习笔记一吃透IOC核心思想小白从零入门最近在学习spring, 写三篇博客做下输出本篇为第一期是Spring零基础入门学习记录专门为小白打磨可放心食用避开晦涩的底层术语用通俗的逻辑讲透Spring核心IOC控制反转。同时搭配可直接运行的实战代码、核心知识点、面试高频考点既能夯实基础也适合日常复盘、技术存档。一、为什么要学SpringSpring核心优势传统Java开发存在很多痛点代码耦合度极高、重复代码泛滥、企业级功能事务、日志实现繁琐、组件整合困难。而Spring框架完美解决了这些问题也是它至今仍是Java后端主流框架的核心原因核心优势分为三点1. 核心架构解耦IOC AOPIOC控制反转依赖注入彻底告别手动new 对象的硬编码将对象的创建、依赖组装、生命周期管理全部交给Spring容器。类与类之间不再强绑定代码解耦单元测试、代码维护难度大幅降低。AOP面向切面编程将日志记录、事务控制、权限校验等非核心业务逻辑抽离出来在不修改业务代码的前提下动态植入保证核心业务代码纯净、专注本职逻辑。2. 企业级功能开箱即用Spring封装了大量繁琐的底层操作最典型的就是声明式事务只需添加一个Transactional注解就能自动完成事务的开启、提交、回滚替代了原生JDBC繁琐的手动事务代码减少冗余代码和人为出错概率。3. 生态成熟集成能力拉满Spring就像Java生态的“万能胶水”可以无缝整合MyBatis、Redis、MQ等所有主流中间件。同时衍生出Spring Boot简化配置、Spring Cloud微服务全套方案覆盖单体项目到分布式微服务项目是职场Java开发的必备技能。二、快速上手Spring IOC基础实战Demo通过一个极简案例直观感受Spring容器托管对象的特性理解IOC的基础使用逻辑。1. XML配置文件applicationContext.xml通过bean标签声明对象交给Spring容器托管?xml version1.0 encodingUTF-8?beansxmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd!-- 将Person类对象交给Spring容器托管id为唯一标识 --beanidpclasscom.may.pojo.Person/bean/beans2. 测试运行代码加载Spring配置文件从容器中获取托管对象publicclassApp{publicstaticvoidmain(String[]args){// 1. 加载XML配置文件初始化Spring容器ApplicationContextacnewClassPathXmlApplicationContext(applicationContext.xml);// 2. 两种方式从容器中获取Bean对象Personp1(Person)ac.getBean(p);Personp2ac.getBean(p,Person.class);// 3. 验证Spring默认单例模式两个对象地址一致System.out.println(p1p2);// 输出true}}运行结论Spring容器默认创建的Bean是单例全局共享同一个对象实例。三、深度理解什么是IOC控制反转IOCInversion of Control控制反转是一种软件设计思想核心将对象创建、依赖管理、生命周期的控制权从开发者代码中剥离反转交给Spring容器统一管理。1. 传统开发 VS IOC开发传统方式高耦合A类依赖B类需要在A类中手动new B()对象创建、依赖绑定由代码控制类与类强耦合修改、测试都很麻烦。IOC方式解耦开发者只需通过XML/注解声明依赖关系无需手动创建对象由Spring容器自动创建、组装依赖最终注入到目标类中。2. IOC与DI的关系重点区分-IOC是核心设计思想目标实现控制权反转、代码解耦-DI依赖注入是实现IOC的核心技术手段落地方式包含构造器注入、Set方法注入、注解自动注入等。3. IOC核心价值彻底消除代码硬编码耦合代码结构更清晰、易维护单元测试可快速Mock依赖组件适配复杂企业级项目迭代。四、手写极简IOC容器模拟Spring底层原理通过手写简易版IOC容器看懂Spring解析XML、创建Bean、托管对象的底层逻辑告别只会用、不懂原理的尴尬。1. XML解析核心代码读取配置文件解析所有bean标签的id和class属性/** * 解析XML配置文件获取所有Bean配置信息 */privatevoidparseXml(Stringxmlpath){// 创建XML解析器SAXReaderreadernewSAXReader();// 获取配置文件路径URLurlthis.getClass().getClassLoader().getResource(xmlpath);try{// 解析XML文档Documentdocumentreader.read(url);// 定位所有beans/bean标签XPathxPathdocument.createXPath(beans/bean);ListElementlistxPath.selectNodes(document);// 遍历标签封装Bean配置信息if(list!nulllist.size()0){for(Elemente:list){Stringide.attributeValue(id);Stringclazze.attributeValue(class);MyBeanmybeannewMyBean(id,clazz);myBeans.add(mybean);}}}catch(DocumentExceptione){thrownewRuntimeException(e);}}2. 反射实例化Bean核心代码根据解析到的类路径通过反射创建对象存入容器Map中/** * 通过反射实例化所有Bean对象存入容器 */privatevoidinstanceBean(){if(myBeans!nullmyBeans.size()0){for(MyBeanbean:myBeans){try{// 反射创建对象实例ObjectobjectClass.forName(bean.getClazz()).newInstance();// 以id为key对象为value存入容器Mapmap.put(bean.getId(),object);}catch(ClassNotFoundException|InstantiationException|IllegalAccessExceptione){thrownewRuntimeException(e);}}}}核心原理总结Spring IOC底层就是XML解析 反射实例化 容器缓存实现对象统一托管。五、Spring Bean的三种实例化方式Spring支持多种Bean实例化方式日常开发以第一种为主后两种适配特殊工厂场景。1. 直接类路径实例化日常开发首选直接通过class属性指定类全路径Spring自动通过空构造器创建对象最简洁、最常用。beanidpclasscom.may.pojo.Person/bean2. 实例化工厂实例化非静态工厂方法适用于工厂类非静态方法创建对象的场景需要先托管工厂Bean再通过工厂创建目标Bean。!-- 1. 托管工厂Bean --beanidfactoryclasscom.msb.factory.PetStore/bean!-- 2. 通过工厂Bean的非静态方法创建目标对象 --beanidafactory-beanfactoryfactory-methodgetAnimalconstructor-argnamepetNamevalue猫/constructor-arg/bean3. 静态工厂实例化静态工厂方法工厂方法为静态方法无需托管工厂Bean直接指定工厂类和静态方法即可。!-- 静态工厂创建Bean替代手动new对象 --beanida2classcom.msb.factory.PetStorefactory-methodgetAnimal2constructor-argnamepetNamevalue猫/constructor-arg/bean六、Bean属性注入方式Spring容器创建对象后可通过两种方式给对象属性赋值开发首选Set设值注入。1. 构造注入有参构造器通过constructor-arg标签匹配有参构造器完成属性赋值。beanidc1classcom.may.pojo.Clazzconstructor-argnamecidvalue1/constructor-argconstructor-argnamecnamevaluejava333/constructor-arg/bean2. 设值注入Set方法首选通过property标签调用Set方法赋值必须保证类存在空构造器否则直接报错。支持基本类型赋值、引用类型Bean关联。beanidcclasscom.msb.pojo.Clazzpropertynamecidvalue1/propertypropertynamecnamevaluejava302班/property/bean!-- 注入引用类型Bean --beanidstuclasscom.msb.pojo.Studentpropertynameagevalue18/propertypropertynamenamevalue露露/propertypropertynameclazzrefc/property/bean重点注意property的name属性对应Set方法名称和类的属性名不强制绑定。3. P名称空间简化注入简化XML配置引入p名称空间简化property标签写法让配置更简洁。?xml version1.0 encodingUTF-8?beansxmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:phttp://www.springframework.org/schema/pxsi:schemaLocationhttp://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd!-- p:属性名基本值 p:属性名-ref引用Beanid --beanidcclasscom.msb.pojo.Clazzp:cid1p:cnamejava302班/beanidstuclasscom.msb.pojo.Studentp:age18p:name露露p:clazz-refc//beans七、高频面试点循环依赖问题及解决方案1. 什么是循环依赖A类依赖B类B类又依赖A类形成双向依赖闭环容器初始化时可能出现对象创建失败。2. 核心解决方案使用Set方法注入 单例Bean默认scope“singleton”Spring单例Bean默认开启三级缓存机制DefaultSingletonBeanRegistry可以暂存未初始化完成的Bean对象1. 创建A对象未完成属性注入先存入三级缓存2. A需要注入B创建B对象B需要注入A3. 从缓存中获取未完成的A注入B4. B初始化完成再完成A的属性注入解决循环依赖。重点避坑构造注入无法解决循环依赖因为构造方法创建对象必须一次性完成参数初始化无缓存缓冲空间。八、Bean自动注入XML注解自动注入核心目的省去手动编写property、constructor-arg的繁琐配置由容器自动匹配依赖Bean。1. XML自动注入两种策略-byName按名称注入容器寻找Bean的id/name与属性名完全一致的对象注入-byType按类型注入容器寻找类型匹配的Bean注入存在多个同类型Bean直接报错NoUniqueBeanDefinitionException。2. 现代开发注解自动注入主流-AutowiredSpring原生注解默认byType注入多Bean匹配时搭配Qualifier(beanId)指定名称-ResourceJava标准注解默认byName注入名称匹配失败则降级byType无Spring框架依赖兼容性更强。记忆口诀XML配两个byName 和 byType实战首选注解配Autowired 找类型Qualifier 定名称Resource 走名称找不到再找类型。九、Bean的Scope作用域Scope决定Spring容器何时创建Bean实例、创建多少个实例核心掌握两个常用值其余了解即可。1. 核心作用域必记-singleton默认单例容器全局仅一个实例容器启动时初始化适用于Service、DAO等无状态对象复用效率极高-prototype多例每次调用getBean()、每次依赖注入都会创建新实例适用于DTO、VO等有状态对象。2. Web专属作用域了解- request单次HTTP请求对应一个实例- session同一个浏览器Session共享一个实例。3. 经典坑点面试高频单例Bean注入多例Bean失效单例Bean在容器启动时仅初始化一次多例Bean只会被注入一次后续调用始终是同一个多例对象。解决方案使用Lookup注解、ObjectFactory、ApplicationContext手动动态获取Bean。十、Bean完整生命周期Spring Bean从创建到销毁分为4个阶段全程由容器托管1. 实例化出生容器启动后通过空构造器创建Bean对象配置lazy-inittrue时延迟到第一次使用时创建。2. 属性填充赋值执行依赖注入Set/构造注入给对象所有属性完成赋值。3. 初始化准备就绪属性赋值完成后执行初始化方法两种实现方式- 自定义init方法XML配置init-method自定义方法名- 实现接口实现InitializingBean接口重写afterPropertiesSet()方法。4. 销毁释放资源容器关闭时调用ctx.close()执行销毁方法两种实现方式- 自定义destroy方法XML配置destroy-method自定义方法名- 实现接口实现DisposableBean接口重写destroy()方法。十一、学习总结本篇作为Spring入门核心重点掌握3个核心1. IOC核心思想控制权反转容器统一管理对象实现代码解耦2. 核心实操Bean三种实例化、两种注入方式、P名称空间简化配置3. 面试高频循环依赖解决方案、Bean作用域、生命周期、自动注入区别。后续将持续更新Spring AOP、注解开发、事务管理等核心知识点循序渐进吃透Spring全家桶注部分内容可能由 AI 生成
返回列表