Spring IOC控制反转详解一、什么是 IOCIOCInversion of Control控制反转是一种设计思想不是什么技术实现。它指的是将对象的创建、管理和依赖关系的控制权从程序代码本身转移到外部容器Spring 容器。传统方式 vs IOC传统方式程序控制publicclassUserService{privateUserDaouserDaonewUserDao();// 自己创建依赖对象publicvoidaddUser(){userDao.save();}}IOC 方式容器控制publicclassUserService{AutowiredprivateUserDaouserDao;// 容器注入依赖对象publicvoidaddUser(){userDao.save();}}二、IOC 的核心概念1. 控制反转控制指对象创建、依赖管理的控制权反转从程序代码反转到外部容器2. 依赖注入DIDependency InjectionDI 是 IOC 的实现方式指容器在创建对象时自动将依赖对象注入到目标对象中。3. IOC 容器Spring 提供的容器实现负责管理 Bean 的生命周期和依赖关系。三、Spring IOC 容器1. 两个核心接口// BeanFactory基础容器提供基本的 IOC 功能publicinterfaceBeanFactory{ObjectgetBean(Stringname);TTgetBean(ClassTrequiredType);booleancontainsBean(Stringname);// ...}// ApplicationContext高级容器扩展了更多功能publicinterfaceApplicationContextextendsBeanFactory{// 国际化支持StringgetMessage(Stringcode,Object[]args,Localelocale);// 资源加载ResourcegetResource(Stringlocation);// 事件发布voidpublishEvent(ApplicationEventevent);// ...}2. 常见的实现类// 1. ClassPathXmlApplicationContext从类路径加载配置ApplicationContextcontextnewClassPathXmlApplicationContext(applicationContext.xml);// 2. FileSystemXmlApplicationContext从文件系统加载配置ApplicationContextcontextnewFileSystemXmlApplicationContext(D:/config/applicationContext.xml);// 3. AnnotationConfigApplicationContext基于注解的配置ApplicationContextcontextnewAnnotationConfigApplicationContext(AppConfig.class);// 4. WebApplicationContextWeb 应用专用// 在 Spring Boot 中自动创建四、Bean 的定义方式1. XML 配置方式?xml version1.0 encodingUTF-8?beansxmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- 定义 Bean --beaniduserServiceclasscom.example.UserService!-- 构造器注入 --constructor-argrefuserDao/!-- 属性注入 --propertynamenamevalue张三//beanbeaniduserDaoclasscom.example.UserDao//beans2. 注解方式推荐// 1. Component通用组件ComponentpublicclassUserService{AutowiredprivateUserDaouserDao;}// 2. Service服务层ServicepublicclassUserService{AutowiredprivateUserDaouserDao;}// 3. Repository数据访问层RepositorypublicclassUserDao{publicvoidsave(){// ...}}// 4. Controller控制层ControllerpublicclassUserController{AutowiredprivateUserServiceuserService;}// 5. Configuration配置类ConfigurationComponentScan(com.example)publicclassAppConfig{BeanpublicUserServiceuserService(){returnnewUserService(userDao());}BeanpublicUserDaouserDao(){returnnewUserDao();}}五、依赖注入的方式1. 构造器注入推荐ServicepublicclassUserService{privatefinalUserDaouserDao;// Spring 4.3 单个构造器可省略 AutowiredAutowiredpublicUserService(UserDaouserDao){this.userDaouserDao;}}优点保证依赖不可变final保证对象初始化完成更容易测试2. Setter 注入ServicepublicclassUserService{privateUserDaouserDao;AutowiredpublicvoidsetUserDao(UserDaouserDao){this.userDaouserDao;}}优点灵活可以在运行时修改适合可选依赖3. 字段注入ServicepublicclassUserService{AutowiredprivateUserDaouserDao;}缺点不能使用 final容易导致空指针不利于测试4. 方法注入ServicepublicclassUserService{privateUserDaouserDao;Autowiredpublicvoidinit(UserDaouserDao){this.userDaouserDao;}}六、Bean 的作用域// 1. singleton默认单例整个容器只有一个实例Scope(singleton)publicclassUserService{}// 2. prototype原型每次获取都创建新实例Scope(prototype)publicclassUserService{}// 3. requestWeb 应用每个请求一个实例Scope(valueWebApplicationContext.SCOPE_REQUEST,proxyModeScopedProxyMode.TARGET_CLASS)publicclassUserService{}// 4. sessionWeb 应用每个会话一个实例Scope(valueWebApplicationContext.SCOPE_SESSION,proxyModeScopedProxyMode.TARGET_CLASS)publicclassUserService{}// 5. applicationWeb 应用ServletContext 生命周期Scope(valueWebApplicationContext.SCOPE_APPLICATION,proxyModeScopedProxyMode.TARGET_CLASS)publicclassUserService{}七、Bean 的生命周期ComponentpublicclassUserServiceimplementsBeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean{// 1. 实例化构造器publicUserService(){System.out.println(1. 实例化);}// 2. 设置属性AutowiredprivateUserDaouserDao;// 3. BeanNameAwareOverridepublicvoidsetBeanName(Stringname){System.out.println(3. BeanNameAware.setBeanName: name);}// 4. BeanFactoryAwareOverridepublicvoidsetBeanFactory(BeanFactorybeanFactory){System.out.println(4. BeanFactoryAware.setBeanFactory);}// 5. ApplicationContextAwareOverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext){System.out.println(5. ApplicationContextAware.setApplicationContext);}// 6. BeanPostProcessor - 前置处理PostConstructpublicvoidpostConstruct(){System.out.println(6. PostConstruct);}// 7. InitializingBeanOverridepublicvoidafterPropertiesSet(){System.out.println(7. InitializingBean.afterPropertiesSet);}// 8. 自定义初始化方法Bean(initMethodinit)publicvoidinit(){System.out.println(8. 自定义初始化方法);}// Bean 可以使用了// 9. PreDestroyPreDestroypublicvoidpreDestroy(){System.out.println(9. PreDestroy);}// 10. DisposableBeanOverridepublicvoiddestroy(){System.out.println(10. DisposableBean.destroy);}// 11. 自定义销毁方法Bean(destroyMethodcleanup)publicvoidcleanup(){System.out.println(11. 自定义销毁方法);}}八、IOC 容器启动流程// 1. 创建容器ApplicationContextcontextnewAnnotationConfigApplicationContext(AppConfig.class);// 内部流程// 1.1 扫描配置类解析 Bean 定义// 1.2 注册 Bean 定义到 BeanDefinitionRegistry// 1.3 实例化单例 Bean非懒加载// 1.4 执行依赖注入// 1.5 执行初始化回调// 1.6 容器启动完成九、自动装配Autowired1. 按类型装配AutowiredprivateUserDaouserDao;// 按类型查找2. 按名称装配AutowiredQualifier(userDaoImpl)// 指定 Bean 名称privateUserDaouserDao;3. 可选依赖Autowired(requiredfalse)// 不存在也不报错privateUserDaouserDao;4. 集合注入AutowiredprivateListUserDaouserDaoList;// 注入所有 UserDao 类型AutowiredprivateMapString,UserDaouserDaoMap;// Bean名称 - Bean实例十、条件化注册 Bean// 1. ConditionalConfigurationpublicclassAppConfig{BeanConditional(WindowsCondition.class)// 满足条件才注册publicUserServicewindowsService(){returnnewWindowsService();}BeanConditional(LinuxCondition.class)publicUserServicelinuxService(){returnnewLinuxService();}}// 2. 常用条件注解ConditionalOnClass(DataSource.class)// 类路径存在ConditionalOnMissingBean(DataSource.class)// 容器中不存在ConditionalOnProperty(nameapp.enabled,havingValuetrue)// 配置属性ConditionalOnExpression(${app.enabled:true})// SpEL 表达式十一、IOC 的优势1. 解耦// 不再需要手动创建和管理对象// 对象之间的关系由容器维护2. 便于测试// 可以轻松注入 Mock 对象TestpublicvoidtestUserService(){UserDaomockDaomock(UserDao.class);UserServiceservicenewUserService(mockDao);// 测试...}3. 配置化管理// 通过配置文件或注解管理对象// 便于维护和修改4. AOP 支持// IOC 容器管理对象便于实现 AOPAspectComponentpublicclassLoggingAspect{Before(execution(* com.example.*.*(..)))publicvoidlogBefore(){// ...}}十二、总结Spring IOC 的核心价值控制反转将对象创建和依赖管理的控制权交给容器依赖注入容器自动将依赖注入到目标对象松耦合对象之间通过接口依赖降低耦合度易测试便于单元测试和集成测试易维护集中管理对象便于配置和修改最佳实践优先使用构造器注入使用注解配置Component、Service 等合理使用 Bean 的作用域理解 Bean 的生命周期合理使用初始化和销毁回调避免循环依赖必要时使用 LazySpring IOC 是 Spring 框架的基石理解它对于掌握 Spring 至关重要