Spring 框架核心知识全解(IOC+DI+AOP + 事务 + 整合)
·
一、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 事务失效场景
- 方法被
try-catch捕获,未抛出异常 - 方法非
public修饰 - 同类中自调用(AOP 代理失效)
九、总结
Spring 核心是IOC 容器管理 Bean、AOP 实现无侵入增强、声明式事务简化数据控制,通过 XML / 注解配置,可快速整合 MyBatis 等框架,是 Java 企业级开发的核心工具。
更多推荐




所有评论(0)