一、Spring 框架概述

1.1 什么是 Spring

Spring 是轻量级 JavaEE 开源框架,由 Rod Johnson 于 2003 年推出,核心是IOC(控制反转)AOP(面向切面编程),可整合各类框架(如 MyBatis),简化企业级开发。

1.2 Spring 核心优势

  • IOC 解耦:容器管理对象,避免硬编码耦合
  • AOP 增强:无侵入抽取日志、事务等重复逻辑
  • 一站式整合:无缝衔接 MyBatis、Redis 等技术
  • 轻量级:核心包体积小,无侵入性

二、IOC(控制反转)

2.1 耦合问题

硬编码new对象(如 Service 中 new Dao),改一处牵连另一处,代码高度耦合。

2.2 IOC 核心概念

  • 控制:对象创建、管理的权限
  • 正转:开发者手动new对象
  • 反转:由Spring IOC 容器创建、管理对象,开发者直接使用

2.3 Spring XML 实现 IOC

2.3.1 导入依赖(pom.xml)

xml

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.20</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.36</version>
</dependency>
2.3.2 核心配置(applicationContext.xml)

xml

<!-- 配置Dao对象 -->
<bean id="userDao" class="com.hg.dao.UserDaoImpl"/>
<!-- 配置Service对象,自动注入 -->
<bean id="userService" class="com.hg.service.UserServiceImpl" autowire="byType"/>
2.3.3 测试获取 Bean

java

运行

// 加载配置文件,初始化IOC容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 根据id和类型获取对象
UserService userService = ac.getBean("userService", UserService.class);

2.4 注解实现 IOC(主流)

2.4.1 开启包扫描(XML)

xml

<context:component-scan base-package="com.hg"/>
2.4.2 IOC 常用注解
  • @Repository:Dao 层
  • @Service:Service 层
  • @Controller:Web 层
  • @Component:通用层
  • @Scope("singleton/prototype"):指定作用域

java

运行

@Repository
public class UserDaoImpl implements UserDao {}

@Service
public class UserServiceImpl implements UserService {}

三、DI(依赖注入)

3.1 DI 概念

DI(Dependency Injection)依赖注入:将 IOC 容器中的依赖对象,自动赋值给当前类属性,实现解耦。

3.2 注入方式

3.2.1 Set 方法注入(常用)
  • 要求:提供setXxx()方法
  • XML 配置

xml

<bean id="userService" class="com.hg.service.UserServiceImpl">
    <property name="userDao" ref="userDao"/>
</bean>
  • Java 代码

java

运行

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}
3.2.2 构造方法注入
  • 要求:提供有参构造
  • XML 配置

xml

<bean id="userService" class="com.hg.service.UserServiceImpl">
    <constructor-arg name="userDao" ref="userDao"/>
</bean>
  • Java 代码

java

运行

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }
}
3.2.3 注解注入(主流)
  • @Autowired按类型注入(常用)
  • @Resource(name="beanId")按名称注入
  • @Value:注入基本类型 / 配置文件值

java

运行

@Service
public class UserServiceImpl implements UserService {
    @Autowired // 自动注入UserDao
    private UserDao userDao;
}

四、BeanFactory 与 ApplicationContext 区别

表格

接口 层级 对象创建时机 特点
BeanFactory 顶级接口 使用时才创建(懒加载) 轻量,功能少
ApplicationContext 子接口 加载配置时创建(饿加载) 功能全,常用

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

5.1 五大作用域

  • singleton单例(默认),容器中仅一个实例
  • prototype多例,每次获取新建对象
  • request:一次请求有效
  • session:一次会话有效
  • application:整个项目有效

5.2 配置作用域

xml

<bean id="userService" class="com.hg.service.UserServiceImpl" scope="singleton"/>

5.3 生命周期

5.3.1 自定义初始化 / 销毁方法

xml

<bean id="userService" class="com.hg.service.UserServiceImpl" 
      init-method="init" destroy-method="destroy"/>
5.3.2 执行流程
  • 单例 Bean:容器创建→构造方法→set 注入→init 初始化→容器关闭→destroy 销毁
  • 多例 Bean:获取对象→构造方法→set 注入→init 初始化→JVM 回收→destroy 销毁

六、AOP(面向切面编程)

6.1 为什么用 AOP

解决代码冗余问题:多个方法需重复执行日志、事务等逻辑,AOP 可无侵入抽取这些通用逻辑。

6.2 AOP 核心概念

  • 切点(Pointcut):要增强的目标方法(如add()
  • 通知(Advice):通用逻辑(日志、事务),分 5 类:
    • @Before:前置通知(方法前)
    • @AfterReturning:后置通知(正常返回后)
    • @AfterThrowing:异常通知(抛出异常时)
    • @After:最终通知(无论正常 / 异常)
    • @Around:环绕通知(包裹方法)
  • 切面(Aspect):绑定通知和切点的过程

6.3 切点表达式

格式:execution(修饰符 返回值 包名.类名.方法名(参数))

java

运行

// 匹配com.hg.service下所有类的所有方法
execution(* com.hg.service.*.*(..))

6.4 注解实现 AOP(主流)

6.4.1 导入依赖

xml

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.3.20</version>
</dependency>
6.4.2 编写切面类

java

运行

@Component
@Aspect // 声明为切面类
public class LogAdvice {
    // 前置通知:匹配service下所有方法
    @Before("execution(* com.hg.service.*.*(..))")
    public void beforeLog() {
        System.out.println("方法执行前:" + new Date());
    }
}
6.4.3 开启 AOP 注解支持(XML)

xml

<aop:aspectj-autoproxy/>

七、Spring 整合 MyBatis

7.1 导入核心依赖(pom.xml)

xml

<!-- Spring -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.20</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.3.20</version>
</dependency>
<!-- MyBatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.9</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.7</version>
</dependency>
<!-- 数据库 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.28</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.16</version>
</dependency>
<!-- 测试 -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.3.20</version>
    <scope>test</scope>
</dependency>

7.2 核心配置(applicationContext.xml)

7.2.1 引入数据库配置(db.properties)

properties

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123456
7.2.2 整合配置

xml

<!-- 1.包扫描 -->
<context:component-scan base-package="com.hg"/>

<!-- 2.引入db.properties -->
<context:property-placeholder location="classpath:db.properties"/>

<!-- 3.配置数据源(Druid) -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driverClass}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

<!-- 4.配置SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!-- 5.扫描Mapper接口 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.hg.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

7.3 整合 Junit 测试

java

运行

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringMyBatisTest {
    @Autowired
    private UserService userService;

    @Test
    public void test() {
        userService.add();
    }
}

八、Spring 事务管理

8.1 事务四大特性(ACID)

  • 原子性:事务不可分割,要么全执行,要么全回滚
  • 一致性:事务前后数据状态一致
  • 隔离性:事务间相互隔离
  • 持久性:提交后数据永久保存

8.2 核心 API

  • PlatformTransactionManager:事务管理器(实现类:DataSourceTransactionManager
  • TransactionDefinition:定义事务属性(隔离级别、传播行为)
  • TransactionStatus:代表事务运行状态

8.3 注解实现事务(主流)

8.3.1 配置事务管理器(XML)

xml

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启事务注解支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
8.3.2 使用@Transactional注解

java

运行

@Service
@Transactional // 类中所有方法开启事务
public class UserServiceImpl implements UserService {
    @Override
    public void add() {
        // 数据库操作
    }
}

8.4 事务失效场景

  1. 方法被try-catch捕获,未抛出异常
  2. 方法非public修饰
  3. 同类中自调用(AOP 代理失效)

九、总结

Spring 核心是IOC 容器管理 BeanAOP 实现无侵入增强声明式事务简化数据控制,通过 XML / 注解配置,可快速整合 MyBatis 等框架,是 Java 企业级开发的核心工具。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐