一、IOC 核心概念:从「手动控制」到「容器托管」
1.1 什么是 IOC?
IOC(Inversion of Control)控制反转 是 Spring 框架的灵魂,核心是将对象的创建、依赖管理、生命周期控制从业务代码中剥离,交由 Spring 容器统一管理。
传统开发模式(无 IOC):
1 2 3 4 5 6 7 8
| public class UserService { private UserRepository userRepository = new UserRepositoryImpl(); public void getUser() { userRepository.findUser(); } }
|
缺点:耦合度极高,修改实现类需要改代码,无法做到开闭原则。
Spring IOC 模式:
1 2 3 4 5 6 7 8 9 10
| @Service public class UserService { @Autowired private UserRepository userRepository; public void getUser() { userRepository.findUser(); } }
|
优势:解耦、可配置、易扩展,开发者只需关注业务逻辑。
1.2 IOC 与 DI 的关系
- IOC:设计思想(控制权反转)
- DI(Dependency Injection)依赖注入:IOC 的实现方式
- 核心逻辑:容器在创建 Bean 时,自动将其依赖的 Bean 注入到当前 Bean 中。
二、IOC 容器工作原理
Spring IOC 容器的核心是 BeanFactory 和 ApplicationContext,后者是前者的超集,提供更多企业级特性。
2.1 容器初始化完整流程

2.2 代码示例:XML 配置方式
步骤 1:定义 Bean 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class UserRepository { public void init() { System.out.println("UserRepository 初始化方法执行"); } public void destroy() { System.out.println("UserRepository 销毁方法执行"); } public void findUser() { System.out.println("查询用户信息"); } }
public class UserService { private UserRepository userRepository;
public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } public void getUser() { userRepository.findUser(); } }
|
步骤 2:编写 XML 配置文件(applicationContext.xml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userRepository" class="com.example.UserRepository" init-method="init" destroy-method="destroy"/>
<bean id="userService" class="com.example.UserService"> <property name="userRepository" ref="userRepository"/> </bean> </beans>
|
步骤 3:启动容器并获取 Bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class SpringIocTest { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) context.getBean("userService"); userService.getUser(); context.close(); } }
|
执行结果:
1 2 3
| UserRepository 初始化方法执行 查询用户信息 UserRepository 销毁方法执行
|
2.3 代码示例:注解配置方式(SpringBoot 主流)
步骤 1:使用注解定义 Bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @Configuration @ComponentScan("com.example") public class AppConfig { @Bean(initMethod = "init", destroyMethod = "destroy") public UserRepository userRepository() { return new UserRepository(); } }
@Service public class UserService { @Autowired private UserRepository userRepository; public void getUser() { userRepository.findUser(); } }
|
字段注入是在对象创建完之后才注入依赖;
循环依赖时,两个对象都在等对方创建完,互相卡住,Spring 救不了。
因为构造器注入是创建时就必须传入依赖,Spring 能提前发现循环,直接报错,不会卡死。
步骤 2:启动注解容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class SpringAnnotationTest { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); UserService userService = context.getBean(UserService.class); userService.getUser(); context.close(); } }
|
三、Bean 生命周期全解析
3.1 单例 Bean 完整生命周期
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
| @Component public class LifeCycleBean implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
public LifeCycleBean() { System.out.println("1. 执行构造方法 - 实例化Bean"); }
@Autowired public void setUserRepository(UserRepository userRepository) { System.out.println("2. 执行Setter方法 - 依赖注入"); }
@Override public void setBeanName(String name) { System.out.println("3. 执行BeanNameAware - Bean名称:" + name); }
@Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("4. 执行BeanFactoryAware - 获取BeanFactory"); }
@PostConstruct public void postConstruct() { System.out.println("6. 执行@PostConstruct注解方法"); }
@Override public void afterPropertiesSet() throws Exception { System.out.println("7. 执行InitializingBean#afterPropertiesSet方法"); }
public void customInit() { System.out.println("8. 执行自定义init-method方法"); }
public void doBusiness() { System.out.println("9. Bean就绪,执行业务方法"); }
@PreDestroy public void preDestroy() { System.out.println("10. 执行@PreDestroy注解方法"); }
@Override public void destroy() throws Exception { System.out.println("11. 执行DisposableBean#destroy方法"); }
public void customDestroy() { System.out.println("12. 执行自定义destroy-method方法"); } }
@Component public class CustomBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof LifeCycleBean) { System.out.println("5. 执行BeanPostProcessor#postProcessBeforeInitialization"); } return bean; }
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof LifeCycleBean) { System.out.println("9. 执行BeanPostProcessor#postProcessAfterInitialization"); } return bean; } }
@Configuration @ComponentScan("com.example") public class LifeCycleConfig { @Bean(initMethod = "customInit", destroyMethod = "customDestroy") public LifeCycleBean lifeCycleBean() { return new LifeCycleBean(); } }
public class LifeCycleTest { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(LifeCycleConfig.class); LifeCycleBean lifeCycleBean = context.getBean(LifeCycleBean.class); lifeCycleBean.doBusiness(); context.close(); } }
|
执行结果(严格按生命周期顺序):
1 2 3 4 5 6 7 8 9 10 11 12 13
| 1. 执行构造方法 - 实例化Bean 2. 执行Setter方法 - 依赖注入 3. 执行BeanNameAware - Bean名称:lifeCycleBean 4. 执行BeanFactoryAware - 获取BeanFactory 5. 执行BeanPostProcessor#postProcessBeforeInitialization 6. 执行@PostConstruct注解方法 7. 执行InitializingBean#afterPropertiesSet方法 8. 执行自定义init-method方法 9. 执行BeanPostProcessor#postProcessAfterInitialization 10. Bean就绪,执行业务方法 11. 执行@PreDestroy注解方法 12. 执行DisposableBean#destroy方法 13. 执行自定义destroy-method方法
|
注解本质是:写在代码里的「元数据标签」,不是配置文件,也不是 XML。
- 注解到底是什么?
- 注解是 Java 语法层面 的东西
- 本质是一个 接口,继承自 java.lang.annotation.Annotation
- 它不直接执行逻辑,只是给代码打标记
- 只有被反射 / 框架解析时才生效
3.2 单例 vs 原型 Bean 对比示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| @Configuration public class ScopeConfig { @Bean @Scope("singleton") public UserRepository singletonRepository() { return new UserRepository(); }
@Bean @Scope("prototype") public UserRepository prototypeRepository() { return new UserRepository(); } }
public class ScopeTest { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class); UserRepository s1 = context.getBean("singletonRepository", UserRepository.class); UserRepository s2 = context.getBean("singletonRepository", UserRepository.class); System.out.println("单例Bean是否同一实例:" + (s1 == s2)); UserRepository p1 = context.getBean("prototypeRepository", UserRepository.class); UserRepository p2 = context.getBean("prototypeRepository", UserRepository.class); System.out.println("原型Bean是否同一实例:" + (p1 == p2)); context.close(); } }
|
四、Bean 自动装配详解
4.1 三大注入注解对比示例
1. @Autowired(Spring 原生)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| public interface UserRepository { void findUser(); }
@Repository("userRepository1") public class UserRepositoryImpl1 implements UserRepository { @Override public void findUser() { System.out.println("UserRepositoryImpl1 查询用户"); } }
@Repository("userRepository2") @Primary public class UserRepositoryImpl2 implements UserRepository { @Override public void findUser() { System.out.println("UserRepositoryImpl2 查询用户"); } }
@Service public class AutowiredDemoService { @Autowired private UserRepository userRepository;
@Autowired @Qualifier("userRepository1") private UserRepository userRepository1;
@Autowired(required = false) private UserRepository userRepository3;
private final UserRepository userRepository4; @Autowired public AutowiredDemoService(@Qualifier("userRepository2") UserRepository userRepository4) { this.userRepository4 = userRepository4; } public void test() { userRepository.findUser(); userRepository1.findUser(); userRepository4.findUser(); } }
|
2. @Resource(JSR-250 标准)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Service public class ResourceDemoService { @Resource(name = "userRepository1") private UserRepository userRepository;
@Resource private UserRepository userRepository2; public void test() { userRepository.findUser(); userRepository2.findUser(); } }
|
3. @Inject(JSR-330 标准)
1 2 3 4 5 6
| <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Service public class InjectDemoService { @Inject private UserRepository userRepository;
@Inject @Named("userRepository1") private UserRepository userRepository1; public void test() { userRepository.findUser(); userRepository1.findUser(); } }
|
4.2 @Autowired 实现原理
@Autowired 的核心实现类是 AutowiredAnnotationBeanPostProcessor,核心流程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) { LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>(); Class<?> targetClass = clazz;
do { final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();
ReflectionUtils.doWithLocalFields(targetClass, field -> { AnnotationAttributes ann = findAutowiredAnnotation(field); if (ann != null) { if (Modifier.isStatic(field.getModifiers())) { return; } boolean required = determineRequiredStatus(ann); currElements.add(new AutowiredFieldElement(field, required)); } });
ReflectionUtils.doWithLocalMethods(targetClass, method -> { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod); if (ann != null) { if (Modifier.isStatic(method.getModifiers())) { return; } boolean required = determineRequiredStatus(ann); PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); currElements.add(new AutowiredMethodElement(method, required, pd)); } });
elements.addAll(0, currElements); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements); }
|
核心逻辑:
- 遍历目标类及其父类的所有字段和方法
- 查找标注 @Autowired 的元素
- 封装为 InjectionMetadata(注入元数据)
- 在 Bean 初始化时,通过反射注入依赖
五、Spring 底层扩展组件实战
5.1 Aware 接口示例(感知容器)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @Component public class AwareDemo implements ApplicationContextAware, BeanNameAware { private ApplicationContext context; private String beanName;
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = applicationContext; String[] beanNames = context.getBeanDefinitionNames(); System.out.println("容器中Bean数量:" + beanNames.length); }
@Override public void setBeanName(String name) { this.beanName = name; System.out.println("当前Bean名称:" + name); }
public void getOtherBean() { UserService userService = context.getBean(UserService.class); userService.getUser(); } }
|
5.2 BeanPostProcessor 实战(自定义注解处理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String value() default ""; }
@Component public class MyAnnotationBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { MyAnnotation annotation = bean.getClass().getAnnotation(MyAnnotation.class); if (annotation != null) { System.out.println("Bean[" + beanName + "]标注了自定义注解,值:" + annotation.value()); } return bean; } }
@Component @MyAnnotation("测试自定义注解") public class MyAnnotationBean { public void test() { System.out.println("自定义注解Bean执行方法"); } }
|
六、SpringBoot 自动配置原理(核心重点)
6.1 自动配置核心思想
SpringBoot 自动配置的本质是:基于约定大于配置的思想,根据类路径下的依赖、配置文件等条件,自动向容器中注册 Bean,无需手动配置。
6.2 自动配置核心流程

6.3 核心注解详解
1. @SpringBootApplication(入口注解)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { // 组件扫描 @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { Class<?>[] exclude() default {}; String[] excludeName() default {}; String[] scanBasePackages() default {}; }
|
核心拆解:
@SpringBootConfiguration:标记当前类为配置类,等价于 @Configuration
@EnableAutoConfiguration:开启自动配置(核心)
@ComponentScan:扫描当前包及其子包下的 @Component 注解类
2. @EnableAutoConfiguration(自动配置核心)
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {}; }
|
核心逻辑:
@AutoConfigurationPackage:将当前主类所在包及子包作为自动配置的基础包
@Import(AutoConfigurationImportSelector.class):加载所有自动配置类
3. AutoConfigurationImportSelector(自动配置加载器)
核心方法:selectImports(),加载 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中的所有自动配置类全限定名。
6.4 条件注解(自动配置的开关)
自动配置不是无条件生效的,而是通过条件注解控制:
| 注解 |
作用 |
| @ConditionalOnClass |
类路径下存在指定类时生效 |
| @ConditionalOnMissingClass |
类路径下不存在指定类时生效 |
| @ConditionalOnBean |
容器中存在指定 Bean 时生效 |
| @ConditionalOnMissingBean |
容器中不存在指定 Bean 时生效 |
| @ConditionalOnProperty |
配置文件中存在指定属性时生效 |
| @ConditionalOnWebApplication |
当前是 Web 应用时生效 |
| @ConditionalOnNotWebApplication |
当前不是 Web 应用时生效 |
示例:DataSourceAutoConfiguration 自动配置类
1 2 3 4 5 6 7 8 9 10 11 12 13
| @AutoConfiguration @ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class}) @ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory") @EnableConfigurationProperties(DataSourceProperties.class) @Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class }) public class DataSourceAutoConfiguration { @Bean @ConditionalOnMissingBean public DataSource dataSource(DataSourceProperties properties) { return properties.initializeDataSourceBuilder().build(); } }
|
6.5 自定义自动配置(实战示例)
步骤 1:创建自动配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @Configuration @ConditionalOnClass(MyService.class) @ConditionalOnProperty(prefix = "my.service", name = "enabled", havingValue = "true", matchIfMissing = true) @EnableConfigurationProperties(MyServiceProperties.class) public class MyServiceAutoConfiguration {
private final MyServiceProperties properties;
public MyServiceAutoConfiguration(MyServiceProperties properties) { this.properties = properties; }
@Bean @ConditionalOnMissingBean public MyService myService() { MyService myService = new MyService(); myService.setName(properties.getName()); myService.setTimeout(properties.getTimeout()); return myService; } }
|
步骤 2:创建配置属性类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @ConfigurationProperties(prefix = "my.service") public class MyServiceProperties { private String name = "defaultName"; private int timeout = 5000;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getTimeout() { return timeout; }
public void setTimeout(int timeout) { this.timeout = timeout; } }
|
步骤 3:创建核心服务类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class MyService { private String name; private int timeout;
public void doSomething() { System.out.println("MyService: name=" + name + ", timeout=" + timeout); }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getTimeout() { return timeout; }
public void setTimeout(int timeout) { this.timeout = timeout; } }
|
步骤 4:注册自动配置类
在 resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中添加:
plaintext
1
| com.example.autoconfig.MyServiceAutoConfiguration
|
步骤 5:测试自定义自动配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @SpringBootApplication public class AutoConfigDemoApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(AutoConfigDemoApplication.class, args); MyService myService = context.getBean(MyService.class); myService.doSomething(); } }
|
6.6 自动配置生效优先级
- 用户自定义 Bean > 自动配置 Bean(@ConditionalOnMissingBean 保证)
- 配置文件属性 > 默认属性(@ConfigurationProperties 绑定)
- 可以通过
spring.autoconfigure.exclude 排除指定自动配置类
七、核心总结
7.1 IOC 核心要点
- IOC 核心:将对象创建和依赖管理交给 Spring 容器,实现解耦。
- Bean 生命周期:实例化 → 依赖注入 → Aware → 前置处理 → 初始化 → 后置处理 → 使用 → 销毁。
- 依赖注入:
- @Autowired:Spring 原生,按类型注入,支持 @Primary/@Qualifier
- @Resource:JSR-250,按名称注入,兼容 JavaEE
- @Inject:JSR-330,标准注解,跨框架兼容
- 扩展点:
- Aware 接口:让 Bean 感知容器
- BeanPostProcessor:Bean 初始化前后自定义处理
- InitializingBean/DisposableBean:生命周期扩展
7.2 SpringBoot 自动配置核心要点
- 核心注解:
@SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan
- 自动配置加载:
AutoConfigurationImportSelector 加载 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中的配置类
- 条件控制:通过
@ConditionalOnXxx 注解控制自动配置是否生效
- 自定义配置:
- 自定义自动配置类 + 配置属性类
- 通过
@ConditionalOnMissingBean 保证用户自定义 Bean 优先级更高
- 配置文件属性通过
@ConfigurationProperties 绑定
最佳实践:
- 依赖注入优先使用构造器注入
- 单例 Bean 注意线程安全
- 多实现注入使用 @Qualifier 指定名称
- 自定义自动配置遵循 SpringBoot 约定,使用条件注解和配置属性绑定
- 排除不需要的自动配置类:
@SpringBootApplication(exclude = XxxAutoConfiguration.class)