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

Spring 框架从入门到精通(第一篇)—— 框架核心与 IOC 容器实践

        作为 Java EE 领域的 “事实标准” 框架,Spring 凭借其 “解耦、灵活、可扩展” 的特性,成为企业级开发的基石。无论是微服务架构还是传统单体应用,Spring 都能提供强大的支撑。本系列博客将分三篇,从基础到实战带你吃透 Spring—— 第一篇聚焦 “框架核心概念” 与 “IOC 容器”,帮你理解 Spring 的设计思想,掌握对象创建与管理的核心能力。

目录

一、为什么要学 Spring?从 Java EE 痛点说起

1.1 传统 Java EE 开发的 3 大痛点

1.2 Spring 的 “救世主” 解决方案

1.3 Spring 的核心架构:不止是 “一层框架”

二、Spring 核心概念:IOC 与 DI 是什么?

2.1 IOC:控制反转,让对象 “自己找主人”

生活案例:从 “自己做饭” 到 “外卖点餐”

代码对比:传统方式 vs Spring IOC 方式

2.2 DI:依赖注入,IOC 的 “具体实现”

DI 的 3 种常见实现方式

三、Spring 环境搭建:从 0 到 1 创建第一个 Spring 项目

3.1 步骤 1:创建 Maven 项目,配置依赖

3.2 步骤 2:创建 Spring 核心配置文件

3.3 步骤 3:创建实体类(POJO)

3.4 步骤 4:编写测试类,从 IOC 容器获取对象

3.5 普通 Java 项目搭建(备选)

四、IOC 容器创建对象的 5 种方式

4.1 方式 1:无参构造创建(默认,最常用)

4.2 方式 2:有参构造创建(适合必填依赖)

配置示例 1:通过参数名匹配

配置示例 2:通过参数索引匹配

配置示例 3:通过参数类型匹配(避免歧义)

4.3 方式 3:实例工厂创建(复用现有工厂类)

步骤 1:创建实例工厂类

步骤 2:配置 Spring 文件

4.4 方式 4:静态工厂创建(无需工厂对象)

步骤 1:创建静态工厂类

步骤 2:配置 Spring 文件

4.5 方式 5:注解创建(企业开发主流)

步骤 1:开启注解扫描

步骤 2:用注解声明 Bean

衍生注解(语义化区分)

五、Bean 的作用域与生命周期:控制对象的 “存活规则”

5.1 Bean 的 6 种作用域

配置作用域:XML 方式 vs 注解方式

测试原型模式:

5.2 Bean 的生命周期:从 “出生” 到 “死亡”

自定义生命周期方法:XML 方式

自定义生命周期方法:注解方式

测试生命周期:

六、总结与下一步预告


一、为什么要学 Spring?从 Java EE 痛点说起

        在学习 Spring 之前,我们先搞懂一个关键问题:为什么 Spring 能成为 Java 开发的 “必修课”? 答案藏在传统 Java EE 开发的痛点里。

1.1 传统 Java EE 开发的 3 大痛点

        企业级应用(如电商系统、OA 系统)往往具备 “结构复杂、事务密集、高并发” 的特点,传统 Java EE 开发面临三大难题:

  • 耦合度高:层与层之间依赖紧密(如 Service 层直接new DaoImpl()),修改一个类可能导致多个类联动修改,维护成本极高;
  • 扩展性差:新增功能时需改动大量现有代码(如添加日志记录、权限检查),不符合 “开闭原则”;
  • 重复代码多:数据库连接管理、事务控制等通用逻辑需在每个方法中重复编写,开发效率低。

举个例子:传统 MVC 开发中,Service 层调用 Dao 层的代码是这样的:

// 传统方式:Service直接依赖Dao实现类,耦合度高
public class UserServiceImpl implements UserService {// 硬编码依赖,DaoImpl修改时需改动此处private UserDao userDao = new UserDaoImpl();@Overridepublic User findUserById(int id) {// 重复的数据库连接、事务控制代码Connection conn = null;try {conn = DBUtil.getConnection();conn.setAutoCommit(false);User user = userDao.find(id);conn.commit();return user;} catch (Exception e) {try { conn.rollback(); } catch (SQLException ex) {}throw new RuntimeException(e);} finally {DBUtil.close(conn); // 重复的资源关闭代码}}
}

这种写法的问题很明显:Service 与 DaoImpl 强耦合,通用逻辑(连接、事务)重复,扩展性差。

1.2 Spring 的 “救世主” 解决方案

        Spring 框架由 Rod Johnson 于 2003 年推出,核心目标是 “解决 Java EE 开发的复杂性”。它的解决方案可以总结为 **“两大核心 + 一个原则”**:

  • 两大核心:IOC(控制反转)解耦对象依赖,AOP(面向切面编程)提取通用逻辑;
  • 一个原则:不重复造轮子(如整合 MyBatis、Hibernate 等现有框架,而非替代它们)。

Spring 的优势体现在三个维度:

  1. 解耦:通过 IOC 容器管理对象创建与依赖,避免硬编码new对象;
  2. 提效:AOP 提取日志、事务等通用逻辑,减少重复代码;
  3. 整合:无缝对接 MyBatis、Spring MVC、Redis 等框架,形成 “一站式” 开发解决方案。

用 Spring 改造后,上述 Service 层代码会变成这样(后续章节详解):

// Spring方式:依赖由容器注入,无硬编码,无重复逻辑
@Service
public class UserServiceImpl implements UserService {// 只依赖接口,不依赖实现类,耦合度低@Autowiredprivate UserDao userDao;@Override@Transactional // 注解声明事务,无需手动控制public User findUserById(int id) {// 只关注业务逻辑,通用逻辑由Spring自动处理return userDao.find(id);}
}

对比可见:Spring 帮我们解决了 “依赖管理” 和 “通用逻辑” 两大问题,开发者只需专注业务实现。

1.3 Spring 的核心架构:不止是 “一层框架”

        

        很多初学者以为 Spring 只是 “一个框架”,其实它是一个分层架构的生态体系,覆盖从持久层到表现层的全链路解决方案。Spring Framework 的核心模块如下图所示,每个模块可独立使用,也可组合协作:

模块分类核心模块功能说明
核心容器Core、Beans、Context提供 IOC 容器支持,负责对象创建、依赖注入;Context 模块扩展容器功能(如国际化、事件)
切面编程AOP、Aspects实现 AOP 功能,支持日志、事务等横切逻辑的提取与织入
数据访问JDBC、ORM、Transactions封装 JDBC 操作,整合 MyBatis/Hibernate,提供声明式事务管理
Web 支持Web、Web MVC支持 Web 开发,提供 Spring MVC 框架,实现 MVC 分层
测试支持Test整合 JUnit,支持 Spring 容器下的单元测试

关键认知:Spring 不是 “替换” 现有框架,而是 “整合” 它们。例如:它不重复实现 ORM 功能,而是通过spring-orm模块让 MyBatis、Hibernate 更易用;它不替代 JDBC,而是通过spring-jdbc模块简化连接管理。

二、Spring 核心概念:IOC 与 DI 是什么?

        IOC(控制反转)是 Spring 的 “灵魂”,理解它就等于掌握了 Spring 的一半。很多初学者对 IOC 的概念感到抽象,我们用 “生活案例 + 代码对比” 帮你彻底搞懂。

2.1 IOC:控制反转,让对象 “自己找主人”

先拆解 “控制反转” 这四个字:

  • 控制:指 “对象创建的控制权”(即new对象的操作);
  • 反转:指对象创建的控制权从 “程序员手动控制” 反转到 “Spring 容器自动控制”。
生活案例:从 “自己做饭” 到 “外卖点餐”

传统开发像 “自己做饭”:想吃什么菜(创建对象),必须自己买食材(new依赖对象)、开火做饭(初始化)、洗碗(资源释放),全程手动操作;
Spring 开发像 “外卖点餐”:你只需告诉平台想吃什么(配置对象需求),平台会自动帮你准备餐食(创建对象)、配送到家(注入依赖),你只需专注 “吃”(业务逻辑)。

代码对比:传统方式 vs Spring IOC 方式
对比维度传统方式(手动控制)Spring IOC 方式(容器控制)
对象创建程序员new对象(如UserDao userDao = new UserDaoImpl()Spring 容器自动创建(配置后通过getBean()获取)
依赖管理硬编码依赖,修改需改代码容器自动注入依赖,无硬编码
资源释放手动关闭连接、释放资源容器自动管理对象生命周期(创建→使用→销毁)

IOC 的核心价值:将对象的 “创建、依赖、销毁” 等通用逻辑交给容器处理,开发者专注业务逻辑,实现 “高内聚、低耦合”。

2.2 DI:依赖注入,IOC 的 “具体实现”

很多人会混淆 IOC 和 DI,其实两者是 “同一概念的不同角度”:

  • IOC:从 “对象控制权” 的角度描述 —— 对象创建权反转到容器;
  • DI(Dependency Injection):从 “依赖传递” 的角度描述 —— 容器在创建对象时,自动将其依赖的对象注入(赋值)给它。

简单说:IOC 是思想,DI 是实现手段。例如:Spring 容器创建UserServiceImpl时,会自动将UserDao对象注入到userDao属性中,无需程序员手动set

DI 的 3 种常见实现方式

Spring 支持三种依赖注入方式,后续章节会详细实战:

  1. 构造注入:通过构造方法传递依赖(适合必填依赖);
  2. 设值注入:通过set方法传递依赖(适合可选依赖,最常用);
  3. 注解注入:通过@Autowired@Resource等注解自动注入(企业开发主流)。

三、Spring 环境搭建:从 0 到 1 创建第一个 Spring 项目

        理解了核心概念后,我们动手搭建 Spring 环境。和 MyBatis 类似,Spring 环境搭建分为 “普通 Java 项目” 和 “Maven 项目” 两种方式,这里重点讲解企业开发常用的Maven 项目搭建

3.1 步骤 1:创建 Maven 项目,配置依赖

新建 Maven 项目(ArtifactId 设为spring-demo),在pom.xml中添加 Spring 核心依赖:

<dependencies><!-- 1. Spring核心依赖:Core + Beans + Context + Expression --><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>4.1.6.RELEASE</version> <!-- 稳定版本,适配多数企业项目 --></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>4.1.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.1.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>4.1.6.RELEASE</version></dependency><!-- 2. 日志依赖:Spring默认依赖commons-logging --><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><!-- 3. 单元测试依赖 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency>
</dependencies>

依赖说明

  • spring-core:提供 Spring 框架的基础服务(如资源加载);
  • spring-beans:提供 BeanFactory(IOC 容器核心);
  • spring-context:提供 ApplicationContext(扩展的 IOC 容器,支持注解、事件等);
  • commons-logging:Spring 的日志依赖,无需额外配置即可打印容器日志。

3.2 步骤 2:创建 Spring 核心配置文件

src/main/resources目录下新建 Spring 核心配置文件applicationContext.xml(命名约定,可自定义),这是 IOC 容器的 “配置入口”:

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 配置Bean:告诉Spring需要管理的对象 --><!-- 语法:<bean id="唯一标识" class="类的全限定名"/> --><bean id="user" class="com.jr.pojo.User"/></beans>

关键标签说明

  • <beans>:根标签,所有 Bean 配置都在其中;
  • <bean>:声明一个需要 Spring 管理的对象,id是唯一标识(后续通过id获取对象),class是类的全限定名(Spring 通过反射创建对象)。

3.3 步骤 3:创建实体类(POJO)

src/main/java/com/jr/pojo目录下创建User类,作为 Spring 管理的对象:

package com.jr.pojo;public class User {private String name;private int age;// 无参构造方法(Spring默认通过无参构造创建对象,必须提供)public User() {}// 有参构造(可选,后续用于构造注入)public User(String name, int age) {this.name = name;this.age = age;}// getter/setter(用于设值注入)public String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }// 业务方法(测试用)public void eat() {System.out.println(name + "(" + age + "岁)在吃汉堡~");}@Overridepublic String toString() {return "User{" + "name='" + name + '\'' + ", age=" + age + '}';}
}

注意:Spring 默认通过 “无参构造” 创建对象,因此实体类必须包含无参构造(若手动写了有参构造,需显式定义无参构造)。

3.4 步骤 4:编写测试类,从 IOC 容器获取对象

src/test/java/com/jr/test目录下创建SpringTest类,通过 Spring 容器获取User对象并调用方法:

package com.jr.test;import com.jr.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringTest {@Testpublic void testIOC() {// 1. 加载Spring核心配置文件,初始化IOC容器// ApplicationContext:Spring容器接口,ClassPathXmlApplicationContext从类路径加载配置文件ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 2. 从容器中获取对象:两种方式// 方式1:通过bean的id获取,返回Object类型,需强制转换User user1 = (User) context.getBean("user");// 方式2:通过id+类型获取,无需强制转换(推荐)User user2 = context.getBean("user", User.class);// 3. 调用对象方法(验证对象由容器创建)user1.setName("张三");user1.setAge(20);user1.eat(); // 输出:张三(20岁)在吃汉堡~// 验证:容器默认创建单例对象(user1和user2是同一个对象)System.out.println(user1 == user2); // 输出:true}
}

运行结果分析

  • 控制台输出张三(20岁)在吃汉堡~,说明User对象由 Spring 容器成功创建;
  • user1 == user2true,说明 Spring 默认创建单例对象(容器中同一个id的 Bean 只存在一个实例)。

3.5 普通 Java 项目搭建(备选)

若不使用 Maven,需手动导入 Spring 核心 Jar 包,步骤如下:

  1. 下载 Spring 核心 Jar 包(官网地址:https://repo.spring.io/libs-release-local/org/springframework/spring/);
  2. 导入以下 Jar 包到项目lib目录:
    • spring-core-4.1.6.RELEASE.jar
    • spring-beans-4.1.6.RELEASE.jar
    • spring-context-4.1.6.RELEASE.jar
    • spring-expression-4.1.6.RELEASE.jar
    • commons-logging-1.2.jar(日志依赖);
  3. 后续步骤(创建配置文件、实体类、测试类)与 Maven 项目一致。

四、IOC 容器创建对象的 5 种方式

        Spring 提供多种创建对象的方式,覆盖不同场景(如默认无参构造、有参构造、工厂模式)。掌握这些方式,能应对复杂项目的对象管理需求。

4.1 方式 1:无参构造创建(默认,最常用)

这是 Spring 创建对象的默认方式,只需在applicationContext.xml中配置<bean>标签,Spring 会自动调用类的无参构造创建对象。

配置示例

<!-- 无参构造创建User对象:id=user,class=User全限定名 -->
<bean id="user" class="com.jr.pojo.User"/>

适用场景:大多数简单对象(如 POJO、Dao、Service),无特殊初始化需求。

4.2 方式 2:有参构造创建(适合必填依赖)

        若对象需要通过有参构造初始化(如创建User时必须指定nameage),可通过<constructor-arg>标签传递参数。

配置示例 1:通过参数名匹配
<!-- 有参构造创建User:name匹配构造方法参数名 -->
<bean id="userWithParam" class="com.jr.pojo.User"><!-- <constructor-arg name="参数名" value="参数值"/> --><constructor-arg name="name" value="李四"/><constructor-arg name="age" value="25"/>
</bean>
配置示例 2:通过参数索引匹配

若构造方法参数名可能变化,可通过index(从 0 开始)指定参数位置:

<!-- 有参构造创建User:index匹配参数位置(0=第一个参数,1=第二个参数) -->
<bean id="userWithIndex" class="com.jr.pojo.User"><constructor-arg index="0" value="王五"/> <!-- 第一个参数:name --><constructor-arg index="1" value="30"/>   <!-- 第二个参数:age -->
</bean>
配置示例 3:通过参数类型匹配(避免歧义)

若构造方法有多个重载(如User(String name, int age)User(int age, String name)),可通过type指定参数类型:

<!-- 有参构造创建User:type指定参数类型,避免歧义 -->
<bean id="userWithType" class="com.jr.pojo.User"><constructor-arg type="java.lang.String" value="赵六"/> <!-- 类型:String --><constructor-arg type="int" value="35"/>               <!-- 类型:int -->
</bean>

测试验证

@Test
public void testConstructorParam() {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");User user = context.getBean("userWithParam", User.class);System.out.println(user); // 输出:User{name='李四', age=25}
}

4.3 方式 3:实例工厂创建(复用现有工厂类)

        若项目中已有 “实例工厂类”(需先创建工厂对象才能生成目标对象),Spring 可通过factory-beanfactory-method调用工厂方法创建对象。

步骤 1:创建实例工厂类
package com.jr.factory;import com.jr.pojo.User;// 实例工厂:需先创建工厂对象,再调用方法生成User
public class UserInstanceFactory {// 工厂方法:生成User对象public User createUser() {// 可在此处添加复杂初始化逻辑(如读取配置、参数校验)return new User("工厂创建的用户", 28);}
}
步骤 2:配置 Spring 文件
<!-- 1. 先创建实例工厂对象 -->
<bean id="userFactory" class="com.jr.factory.UserInstanceFactory"/><!-- 2. 通过工厂对象的方法创建User:factory-bean=工厂id,factory-method=工厂方法名 -->
<bean id="userByInstanceFactory" class="com.jr.pojo.User"factory-bean="userFactory" factory-method="createUser"/>

4.4 方式 4:静态工厂创建(无需工厂对象)

        若工厂类的方法是static(无需创建工厂对象即可调用),Spring 可直接通过classfactory-method调用静态方法创建对象。

步骤 1:创建静态工厂类
package com.jr.factory;import com.jr.pojo.User;// 静态工厂:无需创建工厂对象,直接调用静态方法
public class UserStaticFactory {// 静态工厂方法public static User createUser() {return new User("静态工厂创建的用户", 32);}
}
步骤 2:配置 Spring 文件
<!-- 静态工厂创建User:class=工厂类,factory-method=静态方法名 -->
<bean id="userByStaticFactory" class="com.jr.factory.UserStaticFactory"factory-method="createUser"/>

4.5 方式 5:注解创建(企业开发主流)

        上述 XML 配置方式虽清晰,但当 Bean 数量多时(如 hundreds 个),XML 文件会变得臃肿。Spring 提供注解方式,可通过@Component@Service等注解快速声明 Bean,无需 XML 配置。

步骤 1:开启注解扫描

applicationContext.xml中添加注解扫描配置,告诉 Spring 哪些包下的类需要扫描注解:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context" <!-- 引入context命名空间 -->xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsd"><!-- 开启注解扫描:扫描com.jr包及其子包下的所有类 --><context:component-scan base-package="com.jr"/></beans>
步骤 2:用注解声明 Bean

在类上添加@Component(或其衍生注解),Spring 会自动扫描并创建对象:

package com.jr.pojo;import org.springframework.stereotype.Component;// @Component:声明此类由Spring管理,默认Bean id为"user"(类名首字母小写)
// 可自定义id:@Component("myUser")
@Component
public class User {// 类内容与之前一致...
}
衍生注解(语义化区分)

@Component有三个衍生注解,功能完全相同,仅用于 “语义化区分”(让代码更易读):

  • @Service:用于 Service 层类(如UserServiceImpl);
  • @Repository:用于 Dao 层类(如UserDaoImpl);
  • @Controller:用于 Controller 层类(如UserController)。

示例:Service 层用@Service注解:

package com.jr.service.impl;import com.jr.service.UserService;
import org.springframework.stereotype.Service;@Service // 语义化注解,等同于@Component
public class UserServiceImpl implements UserService {// 业务逻辑...
}

测试验证

@Test
public void testAnnotation() {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 通过默认id(类名首字母小写)获取注解声明的BeanUser user = context.getBean("user", User.class);user.setName("注解创建的用户");user.eat(); // 输出:注解创建的用户(0岁)在吃汉堡~
}

五、Bean 的作用域与生命周期:控制对象的 “存活规则”

        创建对象后,我们还需要控制对象的 “存活规则”—— 比如 “整个应用只有一个实例” 还是 “每次获取都新建实例”,这就需要了解 Bean 的作用域生命周期

5.1 Bean 的 6 种作用域

Spring 提供 6 种作用域,其中单例(singleton) 和原型(prototype) 是核心,其余 4 种仅用于 Web 环境:

作用域说明适用场景
singleton默认值,容器中只存在一个实例,所有请求共享(单例模式)无状态对象(如 Service、Dao)
prototype每次getBean()都创建新实例(原型模式)有状态对象(如 POJO、Request)
requestWeb 环境中,每个 HTTP 请求创建一个实例,请求结束后销毁Web 请求相关对象
sessionWeb 环境中,每个 HTTP Session 创建一个实例,Session 过期后销毁会话相关对象(如用户信息)
applicationWeb 环境中,整个 Web 应用共享一个实例,应用停止后销毁全局配置对象
globalSessionPortlet 环境中,全局 Session 共享一个实例(极少用)Portlet 应用
配置作用域:XML 方式 vs 注解方式
  • XML 方式:通过<bean>scope属性配置:
    <!-- 原型模式:每次获取都新建实例 -->
    <bean id="userPrototype" class="com.jr.pojo.User" scope="prototype"/>
    
  • 注解方式:通过@Scope注解配置:
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component;@Component
    @Scope("prototype") // 配置为原型模式
    public class User {// ...
    }
    
测试原型模式:
@Test
public void testScope() {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 原型模式:两次getBean()获取不同实例User user1 = context.getBean("userPrototype", User.class);User user2 = context.getBean("userPrototype", User.class);System.out.println(user1 == user2); // 输出:false(不同实例)
}

5.2 Bean 的生命周期:从 “出生” 到 “死亡”

Spring Bean 的生命周期可分为 7 个阶段,理解生命周期有助于我们在 “特定时机” 执行自定义逻辑(如初始化资源、释放资源):

  1. 实例化:Spring 通过反射创建 Bean 实例(调用无参构造);
  2. 属性注入:容器为 Bean 的属性注入依赖(调用set方法或构造方法);
  3. 初始化前:调用BeanPostProcessorpostProcessBeforeInitialization(增强 Bean,如 AOP 代理);
  4. 初始化:执行自定义初始化逻辑(如init-method指定的方法、@PostConstruct注解的方法);
  5. 初始化后:调用BeanPostProcessorpostProcessAfterInitialization(最终增强);
  6. 使用:Bean 处于就绪状态,供应用程序调用;
  7. 销毁:容器关闭时,执行自定义销毁逻辑(如destroy-method指定的方法、@PreDestroy注解的方法)。
自定义生命周期方法:XML 方式

通过<bean>init-methoddestroy-method指定初始化、销毁方法:

public class User {// 初始化方法:Bean创建后执行public void init() {System.out.println("User初始化:初始化资源(如加载配置)");}// 销毁方法:容器关闭时执行public void destroy() {System.out.println("User销毁:释放资源(如关闭连接)");}// 其他方法...
}
<!-- 配置初始化和销毁方法 -->
<bean id="userLifecycle" class="com.jr.pojo.User"init-method="init" destroy-method="destroy"/>
自定义生命周期方法:注解方式

通过@PostConstruct(初始化)和@PreDestroy(销毁)注解,无需 XML 配置:

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Component;@Component
public class User {// 初始化方法:Bean创建后执行@PostConstructpublic void init() {System.out.println("User初始化:注解方式");}// 销毁方法:容器关闭时执行@PreDestroypublic void destroy() {System.out.println("User销毁:注解方式");}// 其他方法...
}
测试生命周期:
@Test
public void testLifecycle() {// 注意:需用ClassPathXmlApplicationContext,它有close()方法ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");User user = context.getBean("userLifecycle", User.class);System.out.println("使用User对象...");// 关闭容器,触发销毁方法context.close();
}

运行结果

User初始化:初始化资源(如加载配置)
使用User对象...
User销毁:释放资源(如关闭连接)

六、总结与下一步预告

第一篇博客我们聚焦 Spring 的 “基石”——IOC 容器,核心知识点总结如下:

  1. Spring 的价值:解决传统 Java EE 的 “高耦合、低扩展、重复代码多” 痛点,通过 IOC 和 AOP 简化开发;
  2. IOC 与 DI:IOC 是 “对象控制权反转” 的思想,DI 是 “依赖注入” 的实现手段,两者共同实现解耦;
  3. 环境搭建:Maven 项目通过配置依赖快速搭建,普通项目需手动导入 Jar 包;
  4. Bean 创建方式:无参构造(默认)、有参构造、工厂模式、注解方式(企业主流);
  5. Bean 生命周期:掌握作用域(单例 / 原型)和自定义初始化、销毁方法。

第二篇预告:我们将深入 Spring 的 “另一核心”——依赖注入(DI) 与AOP(面向切面编程),重点讲解:

  • DI 的 3 种实现方式(设值注入、构造注入、注解注入);
  • AOP 的核心概念(切面、通知、切点)与手动实现;
  • Spring AOP 的 XML 与注解配置(日志、权限案例)。

        跟着系列博客一步步实战,你会发现 Spring 的核心逻辑并不复杂 —— 关键是理解 “容器管理对象” 和 “切面提取通用逻辑” 的设计思想,后续的高级特性(如事务、整合 MyBatis)都是基于这两大核心展开的。


文章转载自:

http://I66IMm7D.tphrx.cn
http://mTFjhJrc.tphrx.cn
http://Lc9HzbYp.tphrx.cn
http://OJFWm6l8.tphrx.cn
http://Tt7h5Z0K.tphrx.cn
http://vHkYbd0P.tphrx.cn
http://iD4Js47z.tphrx.cn
http://57NdiIZz.tphrx.cn
http://Vz4MjZg0.tphrx.cn
http://RGZRMlQZ.tphrx.cn
http://951dOgLg.tphrx.cn
http://v9nZGoTt.tphrx.cn
http://bSgGwccv.tphrx.cn
http://QCPOZ2qV.tphrx.cn
http://tKVuWscS.tphrx.cn
http://HyOFPYtj.tphrx.cn
http://e4GHHmYi.tphrx.cn
http://pymJcSpU.tphrx.cn
http://CRs3XT9f.tphrx.cn
http://nV8tGpuL.tphrx.cn
http://N4fGuouV.tphrx.cn
http://l9i2yArW.tphrx.cn
http://VsEwqEY8.tphrx.cn
http://GZtenb8N.tphrx.cn
http://FfbET1kh.tphrx.cn
http://IwfO4hj4.tphrx.cn
http://5t4agTiP.tphrx.cn
http://sBEOmdQh.tphrx.cn
http://kzQWw9Cz.tphrx.cn
http://uDzbGu0b.tphrx.cn
http://www.dtcms.com/a/385108.html

相关文章:

  • 通过DSL生成Jenkins流水线
  • 构建AI智能体:三十四、LangChain SQLDatabaseToolkit终极指南:架构、优势与最佳实践
  • 算法 --- 字符串
  • PDF 文件创建时间属性怎样批量修改详细教程
  • hutool DesensitizedUtil
  • train.py代码学习 自学
  • 安全与效率的平衡术:安全空间
  • 【Unity】事件分发系统的使用示例
  • dinov3 源码 笔记1
  • 飞书项目,再交卷中国智造
  • c++多线程(3)------休眠函数sleep_for和sleep_until
  • 正则表达式 - 元字符
  • RDS-MYSQL,这个RDS是什么?和mysql有什么区别?
  • HarmonyOS事件订阅与通知:后台事件处理
  • 医疗器械飞检常见问题:强生测量系统分析中30%误差的改进方法
  • 可视化数字平台如何重塑未来城市空间?
  • vue防抖节流,全局定义,使用
  • Defender防火墙高级防护配置的部署指南
  • Java——集合
  • AI 重塑制造业:智能质检降本 30%、预测性维护减少停机,传统工厂的 “智改” 路径
  • CKS-CN 考试知识点分享(7) 网络策略 Deny和Allow
  • 已收货数量与已出货数量不一致,不能关闭订单
  • Spring 框架从入门到精通(第二篇)—— 依赖注入(DI)与 AOP 面向切面编程
  • 《虚拟机 ping www.baidu.com失败?Linux ifcfg-ens33 网络配置实操教程》
  • 【LangChain指南】样例选择器(Example selectors)
  • 《深入剖析Kubernetes》02 崭露头角
  • Spring Boot日志
  • 跨域(CORS)和缓存中间件(Redis)深度解析
  • 010SecMain_InitializeDebugAgentPhase2
  • 检索融合方法- Distribution-Based Score Fusion (DBSF)