当前位置: 首页 > news >正文

深入Spring核心:工厂类、Bean生命周期与注解配置详解

在Spring框架的学习中,控制反转(IOC)是基石。掌握了如何让Spring容器创建和管理对象后,我们需要更深入地了解容器本身、对象的生老病死,以及如何用更优雅的注解方式来简化配置。本文将带你从Spring的工厂类入手,逐步解析Bean的生命周期和作用域,并过渡到基于注解的IOP配置实践。


目录

一、Spring的工厂类:ApplicationContext 与 BeanFactory

1. ApplicationContext

2. BeanFactory

3. 核心区别与验证

二、Bean的作用域与生命周期

1. Bean的作用域(Scope)

2. Bean的生命周期

三、迈向注解:基于注解的IOC与DI配置

1. 开启注解扫描

2. 创建对象的注解(取代 )

3. 依赖注入的注解(取代 )

总结


一、Spring的工厂类:ApplicationContext 与 BeanFactory

Spring提供了两种核心的容器(工厂)接口来创建和管理Bean:ApplicationContextBeanFactory。它们构成了IOC容器的基础,但在行为上有显著差异。

1. ApplicationContext

ApplicationContextBeanFactory的子接口,提供了更多企业级功能。在创建容器时,它会立即加载并实例化所有配置的单例Bean,这种“急切加载”方式确保了应用启动后Bean立即可用。常见的实现类有:

ClassPathXmlApplicationContext从类路径下加载XML配置文件。
FileSystemXmlApplicationContext从文件系统路径加载XML配置文件

其类结构关系如下图所示:

2. BeanFactory

BeanFactory是Spring容器最顶层的接口,提供了IOC的基础功能。与ApplicationContext的最大区别在于它的延迟加载机制:只有在首次通过getBean()方法请求某个Bean时,容器才会创建该Bean的实例。它的一个常用实现是XmlBeanFactory(注:Spring 5.x后已不推荐使用)。

3. 核心区别与验证

我们可以通过一个简单的测试来观察二者的区别。假设我们有一个UserServiceImpl,在其无参构造方法中打印日志。

使用ApplicationContext

public class Client { public static void main(String[] args) { new ClassPathXmlApplicationContext("applicationContext.xml"); System.out.println("Spring IOC容器创建好了"); } }

输出结果为:

Bean在容器初始化时就被创建。

使用BeanFactory

public class Client { public static void main(String[] args) { new XmlBeanFactory(new ClassPathResource("applicationContext.xml")); System.out.println("Spring IOC容器创建好了"); } }

输出结果为:

此时Bean并未被创建,直到调用getBean(“userService”)时才会触发构造方法。

在实际开发中,功能更全面的ApplicationContext是更常见的选择。

二、Bean的作用域与生命周期

理解Bean何时创建、如何存在以及何时销毁,是进行高效、正确开发的关键。

1. Bean的作用域(Scope)

通过<bean>标签的scope属性,我们可以控制Bean的实例范围,常用的有以下几种:

singleton (默认)在整个IOC容器中,该Bean定义只存在一个共享实例。适合无状态的Service、DAO等
prototype每次请求该Bean时都会创建一个新的实例。适合有状态的Connection、SqlSession等对象
request/session/application专用于Web环境,将Bean生命周期绑定到对应的Http请求、会话或应用全局

配置示例:<bean id="userService" class="..." scope="prototype"/>

2. Bean的生命周期

Bean从创建到销毁的完整过程,对于单例和多例模式有所不同。

单例Bean的生命周期

[容器启动] —> 构造方法(实例化) —> set方法(依赖注入) —> init方法(自定义初始化) —> [容器关闭] —> destroy方法(自定义销毁)

多例Bean的生命周期

[调用getBean()] —> 构造方法(实例化) —> set方法(依赖注入) —> init方法(自定义初始化) —> [JVM垃圾回收] —> destroy方法(自定义销毁)(注意:Spring容器不管理原型Bean的销毁)

我们可以通过init-methoddestroy-method属性指定自定义的初始化和销毁方法,让Spring在对应时机调用。

三、迈向注解:基于注解的IOC与DI配置

XML配置功能强大但略显繁琐。Spring提供了基于注解的配置方式,其目标与XML完全一致——降低耦合,只是形式更简洁,贴近代码。

1. 开启注解扫描

首先,需要在XML配置中声明注解驱动,并指定要扫描的包。Spring会自动扫描该包及其子包下的类,识别特定注解。

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" ...> <!-- 开启注解扫描,base-package指定扫描的根包 --> <context:component-scan base-package="com.hg"></context:component-scan> </beans>

2. 创建对象的注解(取代<bean>)

以下四个注解功能相同,都用于将类声明为Spring管理的Bean,主要提供语义化区分:

@Component通用注解,用于任何组件
@Controller通常用于标注表现层(如MVC控制器)组件
@Service通常用于标注业务逻辑层组件
@Repository通常用于标注数据访问层(DAO)组件

属性value用于指定Bean在容器中的id。若不指定,则默认id为类名首字母小写。

//@Service("userService") 自定义id为"userService" @Service // 默认id为"userServiceImpl" public class UserServiceImpl implements UserService { ... } @Repository // 默认id为"userDaoImpl" public class UserDaoImpl implements UserDao { ... }

3. 依赖注入的注解(取代<property>)

@Autowired(Spring提供)默认按类型(byType)自动装配。可以与@Qualifier结合使用,实现按名称装配
@Resource(JSR-250标准)默认按名称(byName)自动装配。可通过name属性显式指定Bean的id
@Service public class UserServiceImpl implements UserService { @Autowired // 按类型查找UserDao的实现类并注入 private UserDao userDao; // 或者 @Resource(name="userDaoImpl") // 按名称查找id为"userDaoImpl"的Bean并注入 private UserDao userDao; ... }
@Value用于注入基本数据类型和String类型的值。可以直接注入字面量,也支持从属性文件(.properties)中读取,极大提升了配置的灵活性

① 注入简单值:

@Service public class UserServiceImpl implements UserService { @Value("张三") private String name; @Value("25") private Integer age; }

② 注入属性文件中的值

首先,在XML中加载属性文件:

<context:property-placeholder location="config.properties"/>

然后,在属性文件config.properties中定义:

jdbc.username=root jdbc.password=123456

最后,在类中使用@Value并配合${}占位符注入:

@Service public class UserServiceImpl implements UserService { @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; }

总结

从理解ApplicationContextBeanFactory这两大容器的加载机制差异,到掌握Bean的singletonprototype作用域及其完整的生命周期,是夯实Spring IOC核心概念的关键。而基于注解的配置方式(@Component,@Autowired,@Value等)则代表了更现代、更简洁的Spring开发风格,它通过将配置信息直接写在代码中,减少了XML文件的维护成本,提高了开发效率。从XML到注解,是Spring学习者必须跨越的一道桥梁。

http://www.jsqmd.com/news/470390/

相关文章:

  • 计算机毕业设计springboot基于和Vue的学生管理系统 基于SpringBoot与Vue框架的高校教务信息管理平台设计与实现 采用前后端分离架构的校园学生综合服务系统开发
  • 谢谢你好的啊
  • 3.12打卡
  • OpenClaw安全风险排查:高危漏洞与紧急修复
  • 02计算机组成原理-存储器技术(下)
  • 洛谷P1016——旅行家的预算
  • 2026年中国大模型发展趋势与AGI范式探索:分化、自主学习与Agent战略
  • 2026.3.10Linux
  • [工具] 影子生成器 批量影子生成器 自动修改原偏移坐标文件
  • 太原哪里卖葡萄糖
  • SpringBoot使用AOP优雅的实现系统操作日志的持久化!
  • 动态规划算法的剪枝条件与判定准则的技术6
  • 30 分钟上手 OpenClaw!Windows 搭建跨平台 AI 助手,打破智能生活的边界
  • 短语解析:Oh my!
  • 工业可解释性分析
  • 智慧AI人员行为识别 人员跌倒监测 行人跌倒识别 老人跌倒监控识别 人员躺站识别数据集第10539期
  • 【垃圾箱包装问题-Matlab】【使用遗传算法(GA)解决垃圾箱包装问题Matlab代码】
  • JavaScript性能优化实战玖兴
  • Java注解
  • 通俗具体解释paxos
  • Linux 目录结构与常用命令速查(服务器必备)
  • Context7 MCP:智能文档检索与代码示例系统深度解析
  • speckit + AI IDE开发前后端项目,AI加持开发
  • FPGA内部模块详解之三 FPGA的“记忆细胞”——嵌入式块内存(Block RAM)
  • 手术头灯摄像如何解决术野遮挡问题:手术影像采集技术分析
  • Scala的使用方式
  • 云原生-docker逃逸
  • 基于SpringBoot+Vue的学校网络运维系统毕设项目(完整源码+论文+部署)
  • TMC2660C 寄存器功能位详解--开发笔记
  • 推理框架极简入门与实战指南(非常详细),Nano-vLLM从入门到精通,收藏这一篇就够了!