Spring 从 0 → 1 保姆级笔记:IOC、DI、多配置、Bean 生命周期一次讲透
一、Spring 是什么?为什么 20 年过去还绕不开它?
       一句话:Spring 是 Java 界的“万能胶”,把对象创建、依赖关系、事务、日志、Web、微服务等常用能力做成“积木”,想用哪块拿哪块,真正做到“按需装配”。
2003 年 Rod Johnson 用一本书《Expert One-on-One J2EE Development without EJB》掀桌子:EJB 太重,咱们自己写个轻量级容器!于是 Spring 1.0 诞生。
今天 Spring 已经长成全家桶,但核心还是 2 个关键词:
IOC(Inverse of Control)(控制反转)
把“new 对象”这件事交给 Spring,业务代码只关心“用对象”。AOP(Aspect Oriented Programming)(面向切面)
把“权限、事务、日志”横切逻辑抽出来,通过配置/注解织入,业务代码纯到只含业务。
二、Spring 优点(面试 30 秒版本)
| 优点 | 一句话说明 | 
|---|---|
| 解耦 | 大工厂统一管理对象与依赖 | 
| AOP | 不动业务代码加日志、事务、权限 | 
| 声明式事务 | 几行配置 = 事务控制 | 
| 测试 | 整合 JUnit,@ContextConfiguration 一键启动容器 | 
| 无缝集成 | 官方“亲儿子”:SpringMVC、SpringBoot、SpringCloud;第三方:MyBatis、Hibernate、Quartz… | 
| 简化 JavaEE API | JDBC、JavaMail、JMS 通通模板方法封装 | 
三、IOC 快速体验(5 分钟跑通)
1. 坐标
<!-- 只选核心,其他 starter 再按需加 -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.39</version>
</dependency>2. 接口 + 实现
public interface UserService { void hello(); }public class UserServiceImpl implements UserService {public void hello() { System.out.println("Hello IOC!"); }
}3. 配置文件 applicationContext.xml
<beans ...><bean id="userService" class="com.demo.UserServiceImpl"/>
</beans>4. 启动容器 & 拿对象
ApplicationContext ctx =new ClassPathXmlApplicationContext("applicationContext.xml");
UserService us = (UserService) ctx.getBean("userService");
us.hello();   // Hello IOC!一句话总结:以后再也不 new UserServiceImpl(),让工厂帮你生。
四、Bean 实例化的 3 种姿势
| 方式 | 使用场景 | 配置示例 | 
|---|---|---|
| 无参构造(默认 99%) | 通用 | <bean id="us" class="x.x.UserServiceImpl"/> | 
| 静态工厂 | 创建前想做一些静态校验 | <bean id="us" class="x.x.StaticFactory" factory-method="createUs"/> | 
| 实例工厂 | 必须先有工厂对象 | <bean id="factory" class="x.x.Dfactory"/><bean id="us" factory-bean="factory" factory-method="createUs"/> | 
五、Bean 作用域与生命周期
<bean id="xxx" class="xxx" scope="singleton" init-method="init" destroy-method="destroy"/>| scope | 说明 | 
|---|---|
| singleton | 容器里只 1 份,线程安全由开发者保证 | 
| prototype | 每次 getBean() 都 new | 
| request / session | Web 环境专用,SpringMVC 中才生效 | 
生命周期回调
init-method:对象创建完调destroy-method:singleton 容器关闭时调;prototype 靠 GC六、DI(依赖注入)3 种主流打法
1. set 注入(最常用)
public class OrderServiceImpl {private OrderDao orderDao;private String msg;public void setOrderDao(OrderDao orderDao){...}public void setMsg(String msg){...} }<bean id="orderDao" class="com.dao.OrderDaoImpl"/> <bean id="orderService" class="com.service.OrderServiceImpl"><property name="orderDao" ref="orderDao"/><property name="msg" value="你好"/> </bean>2. 构造注入
public Car(String cname, Double money){...}<bean id="car" class="com.demo.Car"><constructor-arg name="cname" value="大奔"/><constructor-arg name="money" value="400000"/> </bean>3. 集合 / Properties 注入(直接上代码)
<property name="list"><list><value>熊大</value><value>熊二</value></list> </property> <property name="map"><map><entry key="aaa" value="老王"/></map> </property>七、多配置文件:团队开发不打架
方案 1:主文件 import(推荐)
<!-- applicationContext.xml --> <import resource="classpath:dao.xml"/> <import resource="classpath:service.xml"/>方案 2:一次性加载
new ClassPathXmlApplicationContext("dao.xml","service.xml");八、从 XML 到注解再到 JavaConfig(演进彩蛋)
早期 Spring 全是 XML,后来注解 + JavaConfig 成为主流。只要记住 3 个注解,就能脱离 XML:
注解 作用 @Configuration标记这是配置类 @ComponentScan("com.demo")扫包 @Bean把方法返回值扔回容器 @Configuration @ComponentScan("com.demo") public class AppConfig {@Beanpublic UserService userService(){ return new UserServiceImpl(); } }启动:
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);九、小结 & 面试金句
Spring = IOC(解耦) + AOP(扩展)。
IOC 实现 = 工厂 + 反射 + 配置文件 / 注解。
DI 是 IOC 的具体过程:set、构造、自动装配。
Bean 默认单例,可改 prototype / request / session。
多配置
<import>或new ClassPathXmlApplicationContext("a.xml","b.xml")。生命周期
init-method / destroy-method,singleton 容器关闭才销毁。
