资讯详情

IoC底层原理

📅 2026/11/4 1:58:06 | 华诺云谱 👁 阅读
IoC底层原理
Spring是如何创建和管理对象的先读取配置信息注解或XML知道需要管理哪些类// 你写的代码ServicepublicclassUserService{AutowiredprivateUserDaouserDao;}RepositorypublicclassUserDao{}Spring 读到这些注解后心里就知道了 UserService 这个类需要我管理 UserDao 这个类也需要我管理 UserService 里有一个 userDao 字段需要我注入 UserDao 的实例把配置信息封装成 BeanDefinition不是直接new对象先要把Bean对象的信息记录一下/** * BeanDefinition 就像一张对象的图纸 * 它记录了用哪个类创建、怎么初始化、依赖谁、作用域是什么 * * Spring 拿到这个图纸后才按图纸去创建真正的对象 */// Spring 内部大概做了这样的事简化版// 为 UserService 创建一张图纸BeanDefinitionuserServiceBDnewBeanDefinition();userServiceBD.setBeanClass(UserService.class);// 用哪个类userServiceBD.setScope(singleton);// 单例userServiceBD.addDependentBean(userDao);// 依赖 userDao// 为 UserDao 创建一张图纸BeanDefinitionuserDaoBDnewBeanDefinition();userDaoBD.setBeanClass(UserDao.class);userDaoBD.setScope(singleton);根据 BeanDefinition 创建对象实例化根据图纸用反射创建对象/** * 反射 在运行时动态地创建对象、调用方法、访问字段 * * 你写 new UserService() 是在编译时就决定了创建哪个类 * 反射是在运行时拿到类的名字Class对象再去创建实例 */// Spring 用反射创建对象的大致过程简化Class?clazzClass.forName(com.example.service.UserService);// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// 通过类的全限定名拿到 Class 对象// 这就是反射的第一步Objectinstanceclazz.getDeclaredConstructor().newInstance();// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// 通过 Class 对象调用无参构造器创建实例// 这相当于 new UserService()// 但它是动态的不用写死在代码里// 为什么用反射而不用 new// 因为 Spring 在写代码的时候根本不知道要管理哪些类// 它是在运行时读取你的配置才知道的// 所以不可能写死 new XXX()只能用反射动态创建填充依赖依赖注入对象创建好啦但是Autowired字段是空的还需要依赖注入// Spring 内部大致做了这样的事简化版// 1. 创建 UserService 实例UserServiceuserServicenewUserService();// 实际是反射创建的// 2. 找到 UserService 中被 Autowired 标注的字段FielduserDaoFieldUserService.class.getDeclaredField(userDao);// ↑ 反射获取字段userDaoField.setAccessible(true);// ↑ 因为 private 字段不能直接访问需要设置可访问// 3. 从容器中取出已经创建好的 UserDao 实例ObjectuserDaocontainer.getBean(userDao);// ↑ 从 Spring 容器里拿// 4. 把 UserDao 注入到 UserService 的 userDao 字段中userDaoField.set(userService,userDao);// ↑ 相当于 userService.userDao userDao// 但用反射绕过了 private 限制两个重要的接口BeanFactory 和 ApplicationContextBeanFactory最底层的容器接口 │ │ 它是最基本的容器只有创建 Bean 获取 Bean的能力 │ ▼ ApplicationContext更高级的容器接口 │ │ 它继承了 BeanFactory并增加了更多能力 │ - 国际化i18n │ - 事件发布ApplicationEvent │ - 资源加载 │ - AOP 支持 │ ▼ 我们平时用的容器都是 ApplicationContext 的实现 │ ├── ClassPathXmlApplicationContext → 读 XML 配置老项目 ├── AnnotationConfigApplicationContext → 读注解配置现代项目 └── FileSystemXmlApplicationContext → 读文件系统中的 XML 面试回答 BeanFactory 是最基础的容器采用懒加载策略用到时才创建Bean ApplicationContext 是 BeanFactory 的子接口功能更丰富 采用预加载策略启动时就创建所有单例Bean 实际开发中基本都用 ApplicationContext
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑