Spring 框架完全指南

一、Spring 是什么?

1.1 定义

Spring 是一个开源的 Java 企业级应用开发框架,它提供了全面的基础设施支持,让开发者专注于业务逻辑。

Spring 框架的本质:
┌─────────────────────────────────────────┐
│   简化 Java 企业级应用开发的框架           │
│   ├─ 轻量级(相对于 EJB)                 │
│   ├─ 非侵入式(POJO 编程)                │
│   ├─ 控制反转(IoC)                      │
│   ├─ 面向切面编程(AOP)                  │
│   └─ 提供一站式解决方案                   │
└─────────────────────────────────────────┘

1.2 Spring 的发展历程

版本年份重要特性
Spring 1.x2004IoC 容器、AOP 支持
Spring 2.x2006基于注解的配置、AspectJ 集成
Spring 3.x2009Java 配置、SpEL、REST 支持
Spring 4.x2013Java 8 支持、WebSocket、条件注解
Spring 5.x2017响应式编程(WebFlux)、Kotlin 支持
Spring 6.x2022Java 17 基线、原生编译支持

1.3 Spring 生态体系

Spring 生态:
┌──────────────────────────────────────────────────┐
│  Spring Framework(核心框架)                      │
│  ├─ Spring Core(IoC 容器)                       │
│  ├─ Spring AOP(面向切面编程)                    │
│  ├─ Spring Data Access(数据访问)                │
│  └─ Spring Web(Web 应用)                        │
└──────────────────────────────────────────────────┘
                      ↓
┌──────────────────────────────────────────────────┐
│  Spring Boot(快速开发脚手架)                     │
│  ├─ 自动配置                                      │
│  ├─ 内嵌服务器                                    │
│  └─ 开箱即用                                      │
└──────────────────────────────────────────────────┘
                      ↓
┌──────────────────────────────────────────────────┐
│  Spring Cloud(微服务解决方案)                    │
│  ├─ 服务发现(Eureka)                            │
│  ├─ 配置中心(Config)                            │
│  ├─ 负载均衡(Ribbon)                            │
│  ├─ 断路器(Hystrix)                             │
│  └─ API 网关(Gateway)                           │
└──────────────────────────────────────────────────┘
                      ↓
┌──────────────────────────────────────────────────┐
│  其他 Spring 项目                                 │
│  ├─ Spring Data(统一数据访问)                   │
│  ├─ Spring Security(安全框架)                   │
│  ├─ Spring Batch(批处理)                        │
│  └─ Spring Integration(企业集成)                │
└──────────────────────────────────────────────────┘

二、Spring 的核心作用

2.1 解决的核心问题

问题1:对象创建和管理复杂

传统方式

// 传统方式:手动创建对象,耦合度高
public class UserService {
    // 手动创建依赖对象
    private UserDao userDao = new UserDaoImpl();

    public User findUser(Long id) {
        return userDao.findById(id);
    }
}

// 问题:
// 1. UserService 与 UserDaoImpl 紧耦合
// 2. 无法灵活切换实现(如:UserDaoMySqlImpl → UserDaoOracleImpl)
// 3. 难以进行单元测试(无法 Mock UserDao)
// 4. 对象生命周期管理困难

Spring 方式

// Spring 方式:依赖注入,解耦
@Service
public class UserService {
    // Spring 自动注入
    @Autowired
    private UserDao userDao;

    public User findUser(Long id) {
        return userDao.findById(id);
    }
}

// 优势:
// 1. UserService 不关心 UserDao 的具体实现
// 2. 可以通过配置灵活切换实现
// 3. 易于测试(可以注入 Mock 对象)
// 4. Spring 管理对象的完整生命周期
问题2:横切关注点分散

传统方式

// 传统方式:业务代码与系统关注点混杂
public class UserService {
    public void createUser(User user) {
        // 日志记录(横切关注点)
        System.out.println("创建用户: " + user.getName());

        // 事务管理(横切关注点)
        Connection conn = dataSource.getConnection();
        conn.setAutoCommit(false);

        try {
            // 业务逻辑
            userDao.save(user);

            // 提交事务
            conn.commit();

            // 日志记录
            System.out.println("用户创建成功");
        } catch (Exception e) {
            // 回滚事务
            conn.rollback();

            // 日志记录
            System.err.println("用户创建失败: " + e.getMessage());
        }
    }
}

// 问题:
// 1. 业务代码与日志、事务代码混在一起
// 2. 代码重复(每个方法都要写类似代码)
// 3. 维护困难(修改日志格式需要改很多地方)

Spring AOP 方式

// Spring AOP 方式:关注点分离
@Service
public class UserService {
    @Transactional  // 声明式事务
    @Logging        // 自定义日志切面
    public void createUser(User user) {
        // 只关注业务逻辑
        userDao.save(user);
    }
}

// 优势:
// 1. 业务代码清晰,只包含业务逻辑
// 2. 横切关注点集中管理
// 3. 易于维护和修改
问题3:配置和集成复杂

传统方式

// 传统方式:大量配置代码
public class AppConfig {
    public void init() {
        // 配置数据源
        DataSource ds = new BasicDataSource();
        ds.setUrl("jdbc:mysql://localhost:3306/mydb");
        ds.setUsername("root");
        ds.setPassword("password");

        // 配置事务管理器
        DataSourceTransactionManager tm = new DataSourceTransactionManager(ds);

        // 配置 JdbcTemplate
        JdbcTemplate jdbc = new JdbcTemplate(ds);

        // 配置各种 DAO
        UserDao userDao = new UserDaoImpl(jdbc);

        // 配置各种 Service
        UserService userService = new UserService(userDao, tm);

        // ... 大量重复代码
    }
}

Spring 方式

// Spring 方式:声明式配置
@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        return DataSourceBuilder.create()
            .url("jdbc:mysql://localhost:3306/mydb")
            .username("root")
            .password("password")
            .build();
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

或者使用 Spring Boot,连配置都不需要:

# application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: password

2.2 Spring 的六大核心价值

┌─────────────────────────────────────────────────┐
│ 1. 依赖注入(DI)                                │
│    └─ 解耦对象之间的依赖关系                     │
├─────────────────────────────────────────────────┤
│ 2. 面向切面编程(AOP)                           │
│    └─ 分离横切关注点                             │
├─────────────────────────────────────────────────┤
│ 3. 声明式事务管理                                │
│    └─ 简化事务处理                               │
├─────────────────────────────────────────────────┤
│ 4. 简化企业级应用开发                            │
│    └─ 提供一站式解决方案                         │
├─────────────────────────────────────────────────┤
│ 5. 方便集成                                      │
│    └─ 与各种框架无缝整合                         │
├─────────────────────────────────────────────────┤
│ 6. 便于测试                                      │
│    └─ 支持单元测试和集成测试                     │
└─────────────────────────────────────────────────┘

2.3 Spring vs 传统开发对比

维度传统开发Spring
对象创建手动 newIoC 容器管理
依赖管理硬编码依赖依赖注入
生命周期手动管理容器托管
事务管理编程式(手动控制)声明式(@Transactional)
日志记录代码侵入AOP 切面
配置方式繁琐的配置代码注解 + 少量配置
测试难以单元测试易于测试(依赖注入)
扩展性耦合度高松耦合,易扩展

三、Spring 核心原理

3.1 IoC(控制反转)原理

3.1.1 什么是 IoC?

控制反转(Inversion of Control):将对象的创建和依赖关系的管理从应用代码转移到 IoC 容器。

传统方式(正向控制):
Application
  ├─ 创建 UserService
  ├─ 创建 UserDao
  └─ 将 UserDao 注入 UserService

IoC 方式(控制反转):
IoC Container
  ├─ 创建 UserDao
  ├─ 创建 UserService
  └─ 自动注入依赖
           ↓
Application
  └─ 从容器获取 UserService(已注入依赖)

核心思想

“别调用我们,我们会调用你”(Hollywood Principle)

3.1.2 依赖注入(DI)的三种方式

1. 构造器注入(推荐)

@Service
public class UserService {
    private final UserDao userDao;
    private final EmailService emailService;

    // Spring 自动调用构造器注入依赖
    @Autowired  // Spring 4.3+ 单构造器可省略
    public UserService(UserDao userDao, EmailService emailService) {
        this.userDao = userDao;
        this.emailService = emailService;
    }
}

// 优点:
// 1. 依赖对象不可变(final)
// 2. 确保依赖不为 null
// 3. 易于单元测试

2. Setter 注入

@Service
public class UserService {
    private UserDao userDao;

    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

// 优点:
// 1. 可选依赖
// 2. 可以重新注入
// 缺点:
// 1. 依赖可变
// 2. 可能为 null

3. 字段注入(不推荐)

@Service
public class UserService {
    @Autowired
    private UserDao userDao;
}

// 优点:
// 1. 代码简洁
// 缺点:
// 1. 难以测试(无法注入 Mock 对象)
// 2. 违反封装性
// 3. 依赖不明确
3.1.3 Spring IoC 容器的实现原理

核心接口

BeanFactory(根接口)
    ├─ ListableBeanFactory
    ├─ HierarchicalBeanFactory
    └─ AutowireCapableBeanFactory
           ↓
ApplicationContext(高级容器)
    ├─ ClassPathXmlApplicationContext
    ├─ FileSystemXmlApplicationContext
    └─ AnnotationConfigApplicationContext

容器启动流程

// 简化的容器启动流程
public class SimplifiedApplicationContext {

    // 1. 加载配置(扫描注解)
    public void loadBeanDefinitions() {
        // 扫描 @Component、@Service、@Repository、@Controller
        // 解析 @Configuration、@Bean
        // 生成 BeanDefinition(Bean 的元数据)
    }

    // 2. 注册 BeanDefinition
    public void registerBeanDefinitions(BeanDefinition bd) {
        // 存储到 beanDefinitionMap
        beanDefinitionMap.put(bd.getBeanName(), bd);
    }

    // 3. 实例化 Bean
    public Object createBean(BeanDefinition bd) {
        // 3.1 实例化:反射创建对象
        Object bean = bd.getBeanClass().newInstance();

        // 3.2 属性注入:依赖注入
        populateBean(bean, bd);

        // 3.3 初始化:调用初始化方法
        initializeBean(bean, bd);

        return bean;
    }

    // 4. 依赖注入
    public void populateBean(Object bean, BeanDefinition bd) {
        // 查找需要注入的字段/方法
        // 从容器中获取依赖 Bean
        // 反射注入
    }

    // 5. 初始化 Bean
    public Object initializeBean(Object bean, BeanDefinition bd) {
        // 调用 @PostConstruct 方法
        // 调用 InitializingBean.afterPropertiesSet()
        // 调用自定义的 init-method
        return bean;
    }
}

Bean 的完整生命周期

1. 实例化 Bean
   ├─ 反射调用构造器
   └─ 创建 Bean 实例
        ↓
2. 属性注入
   ├─ 依赖查找
   └─ 反射注入依赖
        ↓
3. Aware 接口回调
   ├─ BeanNameAware.setBeanName()
   ├─ BeanFactoryAware.setBeanFactory()
   └─ ApplicationContextAware.setApplicationContext()
        ↓
4. BeanPostProcessor 前置处理
   └─ postProcessBeforeInitialization()
        ↓
5. 初始化
   ├─ @PostConstruct 方法
   ├─ InitializingBean.afterPropertiesSet()
   └─ 自定义 init-method
        ↓
6. BeanPostProcessor 后置处理
   └─ postProcessAfterInitialization()
        ↓
7. Bean 可用
   └─ 放入单例池(singletonObjects)
        ↓
8. 销毁 Bean
   ├─ @PreDestroy 方法
   ├─ DisposableBean.destroy()
   └─ 自定义 destroy-method

核心数据结构

// Spring 容器的核心数据结构(简化)
public class DefaultListableBeanFactory {

    // 1. BeanDefinition 注册表
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

    // 2. 单例池(一级缓存)
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();

    // 3. 早期单例对象(三级缓存,解决循环依赖)
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>();

    // 4. 早期单例对象(二级缓存)
    private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>();
}
3.1.4 循环依赖解决原理

问题:A 依赖 B,B 依赖 A,如何解决?

@Service
public class A {
    @Autowired
    private B b;
}

@Service
public class B {
    @Autowired
    private A a;
}

Spring 的三级缓存解决方案

创建 A:
1. 实例化 A(未注入依赖)
   └─ 放入三级缓存(singletonFactories)
        ↓
2. 注入 A 的依赖:需要 B
   └─ 创建 B
        ↓
创建 B:
3. 实例化 B(未注入依赖)
   └─ 放入三级缓存
        ↓
4. 注入 B 的依赖:需要 A
   ├─ 从三级缓存获取 A 的早期引用
   ├─ 移到二级缓存(earlySingletonObjects)
   └─ 注入到 B
        ↓
5. B 初始化完成
   └─ 放入一级缓存(singletonObjects)
        ↓
6. 将完整的 B 注入到 A
        ↓
7. A 初始化完成
   └─ 放入一级缓存

三级缓存的作用

缓存名称存储内容作用
一级singletonObjects完整的单例 Bean存储最终的 Bean
二级earlySingletonObjects早期的 Bean(未初始化)AOP 代理对象缓存
三级singletonFactoriesBean 工厂解决循环依赖

3.2 AOP(面向切面编程)原理

3.2.1 什么是 AOP?

AOP(Aspect-Oriented Programming):将横切关注点(cross-cutting concerns)从业务逻辑中分离出来。

传统 OOP:
UserService
  ├─ createUser()
  │    ├─ 日志记录 ←┐
  │    ├─ 事务管理 ←┼─ 横切关注点(重复代码)
  │    ├─ 权限检查 ←┤
  │    └─ 业务逻辑  │
  ├─ updateUser()  │
  │    ├─ 日志记录 ←┤
  │    ├─ 事务管理 ←┤
  │    └─ ...      ─┘

AOP 方式:
UserService
  ├─ createUser()  ← 只包含业务逻辑
  └─ updateUser()  ← 只包含业务逻辑

横切关注点(统一管理):
  ├─ LoggingAspect(日志切面)
  ├─ TransactionAspect(事务切面)
  └─ SecurityAspect(权限切面)
3.2.2 AOP 核心概念
概念说明示例
Aspect(切面)横切关注点的模块化日志切面、事务切面
Join Point(连接点)可以插入切面的点方法执行、异常抛出
Pointcut(切点)匹配连接点的表达式execution(* com.example..*.*(..))
Advice(通知)在切点执行的动作Before、After、Around
Target(目标对象)被代理的对象UserService
Proxy(代理对象)AOP 创建的代理UserService$$Proxy
Weaving(织入)将切面应用到目标对象运行时织入(Spring)

完整示例

// 切面类
@Aspect
@Component
public class LoggingAspect {

    // 切点:匹配所有 Service 方法
    @Pointcut("execution(* com.example.service..*.*(..))")
    public void serviceMethods() {}

    // 前置通知
    @Before("serviceMethods()")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("方法执行前: " + joinPoint.getSignature());
    }

    // 后置通知
    @After("serviceMethods()")
    public void logAfter(JoinPoint joinPoint) {
        System.out.println("方法执行后: " + joinPoint.getSignature());
    }

    // 环绕通知(最强大)
    @Around("serviceMethods()")
    public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();

        // 执行目标方法
        Object result = pjp.proceed();

        long end = System.currentTimeMillis();
        System.out.println("方法耗时: " + (end - start) + "ms");

        return result;
    }

    // 返回通知
    @AfterReturning(pointcut = "serviceMethods()", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("方法返回值: " + result);
    }

    // 异常通知
    @AfterThrowing(pointcut = "serviceMethods()", throwing = "ex")
    public void logAfterThrowing(JoinPoint joinPoint, Exception ex) {
        System.out.println("方法抛出异常: " + ex.getMessage());
    }
}
3.2.3 Spring AOP 实现原理

Spring AOP 基于动态代理实现:

1. JDK 动态代理(基于接口)

// 目标对象实现了接口
public interface UserService {
    void createUser(User user);
}

@Service
public class UserServiceImpl implements UserService {
    @Override
    public void createUser(User user) {
        System.out.println("创建用户: " + user.getName());
    }
}

// Spring 使用 JDK 动态代理
UserService proxy = (UserService) Proxy.newProxyInstance(
    classLoader,
    new Class[]{UserService.class},
    new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) {
            // 前置通知
            System.out.println("Before: " + method.getName());

            // 执行目标方法
            Object result = method.invoke(target, args);

            // 后置通知
            System.out.println("After: " + method.getName());

            return result;
        }
    }
);

2. CGLIB 动态代理(基于子类)

// 目标对象没有实现接口
@Service
public class UserService {
    public void createUser(User user) {
        System.out.println("创建用户: " + user.getName());
    }
}

// Spring 使用 CGLIB 创建子类代理
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback(new MethodInterceptor() {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
        // 前置通知
        System.out.println("Before: " + method.getName());

        // 执行目标方法(调用父类方法)
        Object result = proxy.invokeSuper(obj, args);

        // 后置通知
        System.out.println("After: " + method.getName());

        return result;
    }
});

UserService proxy = (UserService) enhancer.create();

JDK 代理 vs CGLIB 代理

维度JDK 动态代理CGLIB 代理
实现方式基于接口(Proxy.newProxyInstance)基于继承(生成子类)
要求目标类必须实现接口目标类不能是 final
性能略低略高
Spring 选择有接口优先使用无接口时使用

AOP 代理创建流程

1. Bean 创建阶段
   ├─ 实例化目标对象
   └─ 属性注入
        ↓
2. BeanPostProcessor 后置处理
   ├─ AbstractAutoProxyCreator.postProcessAfterInitialization()
   ├─ 查找匹配的 Advisor(切面)
   └─ 如果有匹配的切面 → 创建代理
        ↓
3. 创建代理对象
   ├─ 判断:目标类是否实现接口?
   ├─ 是 → JDK 动态代理
   └─ 否 → CGLIB 代理
        ↓
4. 返回代理对象
   └─ 放入容器(代替原始 Bean)

方法调用流程

用户调用
  ↓
代理对象.method()
  ↓
InvocationHandler.invoke() / MethodInterceptor.intercept()
  ├─ 获取该方法的拦截器链(Advisor Chain)
  ├─ 依次执行拦截器
  │   ├─ @Before 通知
  │   ├─ @Around 通知(前)
  │   ├─ 目标方法执行 ← method.invoke(target, args)
  │   ├─ @Around 通知(后)
  │   ├─ @After 通知
  │   └─ @AfterReturning / @AfterThrowing
  └─ 返回结果

3.3 Spring 事务管理原理

3.3.1 声明式事务
@Service
public class UserService {

    @Transactional  // 声明式事务
    public void createUser(User user) {
        userDao.save(user);
        accountDao.createAccount(user.getId());
        // 如果抛出异常,自动回滚
    }
}

等价于

// 编程式事务(传统方式)
public void createUser(User user) {
    TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
    try {
        userDao.save(user);
        accountDao.createAccount(user.getId());

        transactionManager.commit(status);
    } catch (Exception e) {
        transactionManager.rollback(status);
        throw e;
    }
}
3.3.2 事务实现原理

基于 AOP 实现

@Transactional 方法
  ↓
TransactionInterceptor(事务拦截器)
  ↓
1. 开启事务
   └─ transactionManager.getTransaction()
  ↓
2. 执行目标方法
   └─ method.proceed()
  ↓
3. 提交或回滚
   ├─ 成功 → transactionManager.commit()
   └─ 异常 → transactionManager.rollback()

事务管理器体系

PlatformTransactionManager(顶层接口)
  ├─ DataSourceTransactionManager(JDBC)
  ├─ HibernateTransactionManager(Hibernate)
  ├─ JpaTransactionManager(JPA)
  └─ JtaTransactionManager(分布式事务)

事务传播行为

传播行为说明示例场景
REQUIRED(默认)有事务加入,无事务新建最常用
REQUIRES_NEW总是新建事务,挂起当前事务记录日志(不受外层事务影响)
NESTED嵌套事务(保存点)部分回滚
SUPPORTS有事务加入,无事务以非事务执行查询方法
NOT_SUPPORTED以非事务执行,挂起当前事务批处理
NEVER以非事务执行,有事务抛异常强制非事务
MANDATORY必须在事务中执行,无事务抛异常强制事务

示例

@Service
public class OrderService {

    @Autowired
    private LogService logService;

    @Transactional
    public void createOrder(Order order) {
        orderDao.save(order);  // 主业务

        // 记录日志(独立事务,不受主事务影响)
        logService.log("订单创建: " + order.getId());

        // 如果后续出错,订单回滚,但日志已提交
    }
}

@Service
public class LogService {

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void log(String message) {
        logDao.save(message);
        // 独立提交,不受外层事务影响
    }
}

四、Spring 核心模块

4.1 模块架构

Spring Framework
├─ Core Container(核心容器)
│  ├─ spring-core(核心工具类)
│  ├─ spring-beans(Bean 管理)
│  ├─ spring-context(应用上下文)
│  └─ spring-expression(SpEL 表达式)
│
├─ AOP
│  ├─ spring-aop(AOP 支持)
│  └─ spring-aspects(AspectJ 集成)
│
├─ Data Access/Integration(数据访问)
│  ├─ spring-jdbc(JDBC 支持)
│  ├─ spring-tx(事务管理)
│  ├─ spring-orm(ORM 集成)
│  └─ spring-jms(消息队列)
│
├─ Web
│  ├─ spring-web(Web 基础)
│  ├─ spring-webmvc(Spring MVC)
│  └─ spring-webflux(响应式 Web)
│
└─ Test
   └─ spring-test(测试支持)

4.2 核心容器详解

4.2.1 spring-core

核心工具类

// 1. 资源访问
Resource resource = new ClassPathResource("config.properties");
InputStream is = resource.getInputStream();

// 2. 类型转换
ConversionService conversionService = new DefaultConversionService();
Integer num = conversionService.convert("123", Integer.class);

// 3. 环境抽象
Environment env = applicationContext.getEnvironment();
String profile = env.getActiveProfiles()[0];
4.2.2 spring-beans

Bean 定义和管理

// Bean 定义
BeanDefinition bd = BeanDefinitionBuilder
    .rootBeanDefinition(UserService.class)
    .setScope(BeanDefinition.SCOPE_SINGLETON)
    .addPropertyValue("userDao", userDao)
    .getBeanDefinition();

// Bean 工厂
BeanFactory beanFactory = new XmlBeanFactory(resource);
UserService userService = beanFactory.getBean(UserService.class);
4.2.3 spring-context

应用上下文

// 注解配置
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

// XML 配置
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

// Web 环境
WebApplicationContext webContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);

4.3 数据访问模块

4.3.1 spring-jdbc

JdbcTemplate 简化 JDBC 操作

@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public User findById(Long id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), id);
    }

    @Override
    public List<User> findAll() {
        String sql = "SELECT * FROM users";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
    }

    @Override
    public int save(User user) {
        String sql = "INSERT INTO users(name, email) VALUES(?, ?)";
        return jdbcTemplate.update(sql, user.getName(), user.getEmail());
    }
}

优势

  • 自动资源管理(Connection、Statement、ResultSet)
  • 异常转换(SQLException → DataAccessException)
  • 简化代码
4.3.2 spring-tx

事务管理

@Configuration
@EnableTransactionManagement
public class TransactionConfig {

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

@Service
public class UserService {

    @Transactional(
        propagation = Propagation.REQUIRED,
        isolation = Isolation.READ_COMMITTED,
        timeout = 30,
        rollbackFor = Exception.class
    )
    public void createUser(User user) {
        userDao.save(user);
    }
}

4.4 Web 模块

4.4.1 Spring MVC

核心组件

请求流程:
Client Request
  ↓
DispatcherServlet(前端控制器)
  ↓
HandlerMapping(处理器映射)
  └─ 找到对应的 Controller
        ↓
HandlerAdapter(处理器适配器)
  └─ 执行 Controller 方法
        ↓
Controller(控制器)
  └─ 返回 ModelAndView
        ↓
ViewResolver(视图解析器)
  └─ 解析视图名称
        ↓
View(视图)
  └─ 渲染响应
        ↓
Client Response

示例

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }

    @PutMapping("/{id}")
    public User updateUser(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        return userService.update(user);
    }

    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.delete(id);
    }
}

五、Spring 重要的类和接口

5.1 核心容器类

5.1.1 BeanFactory 体系
// 1. BeanFactory - 根接口
public interface BeanFactory {
    Object getBean(String name);
    <T> T getBean(String name, Class<T> requiredType);
    <T> T getBean(Class<T> requiredType);
    boolean containsBean(String name);
    boolean isSingleton(String name);
    boolean isPrototype(String name);
}

// 2. ListableBeanFactory - 可列举 Bean
public interface ListableBeanFactory extends BeanFactory {
    String[] getBeanDefinitionNames();
    <T> Map<String, T> getBeansOfType(Class<T> type);
    String[] getBeanNamesForType(Class<?> type);
}

// 3. ConfigurableBeanFactory - 可配置的 Bean 工厂
public interface ConfigurableBeanFactory extends BeanFactory {
    void setBeanClassLoader(ClassLoader beanClassLoader);
    void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
    void destroySingletons();
}

// 4. DefaultListableBeanFactory - 默认实现
public class DefaultListableBeanFactory
    extends AbstractAutowireCapableBeanFactory
    implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {

    // Bean 定义注册表
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

    // 单例池
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
}
5.1.2 ApplicationContext 体系
// 1. ApplicationContext - 应用上下文
public interface ApplicationContext extends EnvironmentCapable,
    ListableBeanFactory, HierarchicalBeanFactory,
    MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

    String getId();
    String getDisplayName();
    long getStartupDate();
    ApplicationContext getParent();
    AutowireCapableBeanFactory getAutowireCapableBeanFactory();
}

// 2. ConfigurableApplicationContext - 可配置的应用上下文
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
    void setEnvironment(ConfigurableEnvironment environment);
    void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);
    void refresh() throws BeansException;
    void close();
}

// 3. 常用实现类
public class AnnotationConfigApplicationContext
    extends GenericApplicationContext
    implements AnnotationConfigRegistry {

    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        this();
        register(componentClasses);
        refresh();
    }
}

public class ClassPathXmlApplicationContext
    extends AbstractXmlApplicationContext {

    public ClassPathXmlApplicationContext(String configLocation) {
        this(new String[]{configLocation}, true, null);
    }
}

5.2 Bean 生命周期相关接口

// 1. BeanPostProcessor - Bean 后置处理器
public interface BeanPostProcessor {
    // Bean 初始化前调用
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }

    // Bean 初始化后调用
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}

// 2. InitializingBean - 初始化 Bean
public interface InitializingBean {
    void afterPropertiesSet() throws Exception;
}

// 3. DisposableBean - 销毁 Bean
public interface DisposableBean {
    void destroy() throws Exception;
}

// 4. Aware 接口系列
public interface BeanNameAware extends Aware {
    void setBeanName(String name);
}

public interface BeanFactoryAware extends Aware {
    void setBeanFactory(BeanFactory beanFactory);
}

public interface ApplicationContextAware extends Aware {
    void setApplicationContext(ApplicationContext applicationContext);
}

使用示例

@Component
public class UserService implements BeanNameAware, ApplicationContextAware,
    InitializingBean, DisposableBean {

    private String beanName;
    private ApplicationContext applicationContext;

    // 1. BeanNameAware 回调
    @Override
    public void setBeanName(String name) {
        this.beanName = name;
        System.out.println("BeanNameAware: " + name);
    }

    // 2. ApplicationContextAware 回调
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        System.out.println("ApplicationContextAware");
    }

    // 3. 初始化方法
    @PostConstruct
    public void init() {
        System.out.println("@PostConstruct");
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("InitializingBean.afterPropertiesSet()");
    }

    // 4. 销毁方法
    @PreDestroy
    public void preDestroy() {
        System.out.println("@PreDestroy");
    }

    @Override
    public void destroy() {
        System.out.println("DisposableBean.destroy()");
    }
}

5.3 AOP 相关类

// 1. Advisor - 通知器(Pointcut + Advice)
public interface Advisor {
    Advice getAdvice();
}

public interface PointcutAdvisor extends Advisor {
    Pointcut getPointcut();
}

// 2. Pointcut - 切点
public interface Pointcut {
    ClassFilter getClassFilter();
    MethodMatcher getMethodMatcher();
}

// 3. Advice - 通知
public interface MethodBeforeAdvice extends BeforeAdvice {
    void before(Method method, Object[] args, @Nullable Object target);
}

public interface AfterReturningAdvice extends AfterAdvice {
    void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target);
}

// 4. JoinPoint - 连接点
public interface JoinPoint {
    Object[] getArgs();
    Signature getSignature();
    Object getTarget();
    Object getThis();
}

public interface ProceedingJoinPoint extends JoinPoint {
    Object proceed() throws Throwable;
    Object proceed(Object[] args) throws Throwable;
}

5.4 事务相关类

// 1. PlatformTransactionManager - 事务管理器
public interface PlatformTransactionManager extends TransactionManager {
    TransactionStatus getTransaction(@Nullable TransactionDefinition definition);
    void commit(TransactionStatus status);
    void rollback(TransactionStatus status);
}

// 2. TransactionDefinition - 事务定义
public interface TransactionDefinition {
    int getPropagationBehavior();  // 传播行为
    int getIsolationLevel();        // 隔离级别
    int getTimeout();               // 超时时间
    boolean isReadOnly();           // 只读标识
}

// 3. TransactionStatus - 事务状态
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
    boolean isNewTransaction();
    boolean hasSavepoint();
    void setRollbackOnly();
    boolean isRollbackOnly();
    boolean isCompleted();
}

// 4. @Transactional 注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Transactional {
    Propagation propagation() default Propagation.REQUIRED;
    Isolation isolation() default Isolation.DEFAULT;
    int timeout() default -1;
    boolean readOnly() default false;
    Class<? extends Throwable>[] rollbackFor() default {};
    Class<? extends Throwable>[] noRollbackFor() default {};
}

5.5 Web MVC 相关类

// 1. DispatcherServlet - 前端控制器
public class DispatcherServlet extends FrameworkServlet {
    @Override
    protected void doService(HttpServletRequest request, HttpServletResponse response) {
        doDispatch(request, response);
    }

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
        // 1. 获取 Handler
        HandlerExecutionChain mappedHandler = getHandler(request);

        // 2. 获取 HandlerAdapter
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

        // 3. 执行 Handler
        ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());

        // 4. 处理视图
        processDispatchResult(request, response, mappedHandler, mv, dispatchException);
    }
}

// 2. HandlerMapping - 处理器映射
public interface HandlerMapping {
    @Nullable
    HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}

// 3. HandlerAdapter - 处理器适配器
public interface HandlerAdapter {
    boolean supports(Object handler);
    @Nullable
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler);
}

// 4. ViewResolver - 视图解析器
public interface ViewResolver {
    @Nullable
    View resolveViewName(String viewName, Locale locale) throws Exception;
}

5.6 常用注解

// 1. 组件注解
@Component    // 通用组件
@Service      // 业务层组件
@Repository   // 数据访问层组件
@Controller   // 控制层组件
@RestController  // RESTful 控制器

// 2. 配置注解
@Configuration   // 配置类
@Bean            // Bean 定义
@ComponentScan   // 组件扫描
@Import          // 导入配置

// 3. 依赖注入注解
@Autowired       // 自动装配
@Qualifier       // 指定 Bean 名称
@Resource        // JSR-250 注入
@Value           // 注入值

// 4. 作用域注解
@Scope           // Bean 作用域
@Lazy            // 延迟初始化

// 5. AOP 注解
@Aspect          // 切面
@Pointcut        // 切点
@Before          // 前置通知
@After           // 后置通知
@Around          // 环绕通知
@AfterReturning  // 返回通知
@AfterThrowing   // 异常通知

// 6. 事务注解
@Transactional   // 声明式事务
@EnableTransactionManagement  // 启用事务管理

// 7. Web MVC 注解
@RequestMapping  // 请求映射
@GetMapping      // GET 请求
@PostMapping     // POST 请求
@PutMapping      // PUT 请求
@DeleteMapping   // DELETE 请求
@PathVariable    // 路径变量
@RequestParam    // 请求参数
@RequestBody     // 请求体
@ResponseBody    // 响应体

六、Spring 使用指南

6.1 快速开始

6.1.1 Maven 依赖
<dependencies>
    <!-- Spring Context(包含 core、beans、context、expression) -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.30</version>
    </dependency>

    <!-- Spring AOP -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>5.3.30</version>
    </dependency>

    <!-- AspectJ -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.19</version>
    </dependency>

    <!-- Spring JDBC -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.30</version>
    </dependency>

    <!-- Spring Web MVC -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.30</version>
    </dependency>
</dependencies>
6.1.2 基于注解的配置(推荐)
// 1. 配置类
@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy
@EnableTransactionManagement
public class AppConfig {

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

// 2. 启动应用
public class Application {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        UserService userService = context.getBean(UserService.class);
        userService.createUser(new User("张三", "zhangsan@example.com"));
    }
}
6.1.3 基于 XML 的配置(传统方式)
<!-- applicationContext.xml -->
<?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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 启用注解扫描 -->
    <context:component-scan base-package="com.example"/>

    <!-- 启用 AOP -->
    <aop:aspectj-autoproxy/>

    <!-- 数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
        <property name="username" value="root"/>
        <property name="password" value="password"/>
    </bean>

    <!-- JdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 启用事务注解 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
// 启动应用
public class Application {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserService userService = context.getBean(UserService.class);
        userService.createUser(new User("张三", "zhangsan@example.com"));
    }
}

6.2 完整示例

6.2.1 实体类
public class User {
    private Long id;
    private String name;
    private String email;
    private Date createdAt;

    // 构造器、Getter、Setter
}
6.2.2 DAO 层
public interface UserDao {
    int save(User user);
    User findById(Long id);
    List<User> findAll();
    int update(User user);
    int delete(Long id);
}

@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int save(User user) {
        String sql = "INSERT INTO users(name, email, created_at) VALUES(?, ?, ?)";
        return jdbcTemplate.update(sql, user.getName(), user.getEmail(), new Date());
    }

    @Override
    public User findById(Long id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql,
            new BeanPropertyRowMapper<>(User.class), id);
    }

    @Override
    public List<User> findAll() {
        String sql = "SELECT * FROM users";
        return jdbcTemplate.query(sql,
            new BeanPropertyRowMapper<>(User.class));
    }

    @Override
    public int update(User user) {
        String sql = "UPDATE users SET name = ?, email = ? WHERE id = ?";
        return jdbcTemplate.update(sql,
            user.getName(), user.getEmail(), user.getId());
    }

    @Override
    public int delete(Long id) {
        String sql = "DELETE FROM users WHERE id = ?";
        return jdbcTemplate.update(sql, id);
    }
}
6.2.3 Service 层
public interface UserService {
    User createUser(User user);
    User findUser(Long id);
    List<User> findAllUsers();
    User updateUser(User user);
    void deleteUser(Long id);
}

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Transactional
    @Override
    public User createUser(User user) {
        userDao.save(user);
        return user;
    }

    @Override
    public User findUser(Long id) {
        return userDao.findById(id);
    }

    @Override
    public List<User> findAllUsers() {
        return userDao.findAll();
    }

    @Transactional
    @Override
    public User updateUser(User user) {
        userDao.update(user);
        return user;
    }

    @Transactional
    @Override
    public void deleteUser(Long id) {
        userDao.delete(id);
    }
}
6.2.4 AOP 日志切面
@Aspect
@Component
@Slf4j
public class LoggingAspect {

    @Pointcut("execution(* com.example.service..*.*(..))")
    public void serviceLayer() {}

    @Around("serviceLayer()")
    public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
        String className = pjp.getTarget().getClass().getSimpleName();
        String methodName = pjp.getSignature().getName();
        Object[] args = pjp.getArgs();

        log.info("{}. {} 开始执行,参数:{}", className, methodName, Arrays.toString(args));

        long start = System.currentTimeMillis();
        Object result = null;

        try {
            result = pjp.proceed();
            long end = System.currentTimeMillis();

            log.info("{}.{} 执行成功,耗时:{}ms,返回值:{}",
                className, methodName, (end - start), result);

            return result;
        } catch (Exception e) {
            log.error("{}.{} 执行失败:{}", className, methodName, e.getMessage());
            throw e;
        }
    }
}
6.2.5 Controller 层(Spring MVC)
@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User created = userService.createUser(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(created);
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.findUser(id);
        return ResponseEntity.ok(user);
    }

    @GetMapping
    public ResponseEntity<List<User>> getAllUsers() {
        List<User> users = userService.findAllUsers();
        return ResponseEntity.ok(users);
    }

    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        User updated = userService.updateUser(user);
        return ResponseEntity.ok(updated);
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}

七、Spring Boot 简介

7.1 Spring Boot 的作用

Spring Boot 简化了 Spring 应用的开发:

传统 SpringSpring Boot
大量 XML 配置自动配置
依赖版本管理复杂starter 依赖
部署需要外部容器内嵌服务器
配置分散统一配置(application.yml)

7.2 Spring Boot 快速开始

<!-- pom.xml -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.1</version>
</parent>

<dependencies>
    <!-- Web 应用 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- MySQL -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
    </dependency>
</dependencies>
# application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: password
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
// 启动类
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// 实体类
@Entity
@Table(name = "users")
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String email;
}

// Repository
public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByName(String name);
}

// Service
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public User save(User user) {
        return userRepository.save(user);
    }
}

// Controller
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping
    public User create(@RequestBody User user) {
        return userService.save(user);
    }
}

7.3 Spring Boot 核心特性

1. 自动配置(Auto-Configuration)
   └─ 根据 classpath 自动配置 Bean

2. Starter 依赖
   ├─ spring-boot-starter-web(Web 应用)
   ├─ spring-boot-starter-data-jpa(JPA)
   ├─ spring-boot-starter-security(安全)
   └─ spring-boot-starter-test(测试)

3. 内嵌服务器
   ├─ Tomcat(默认)
   ├─ Jetty
   └─ Undertow

4. 生产就绪特性
   ├─ Actuator(监控端点)
   ├─ Metrics(指标收集)
   └─ Health Check(健康检查)

5. 外部化配置
   ├─ application.properties
   ├─ application.yml
   ├─ 环境变量
   └─ 命令行参数

八、Spring 最佳实践

8.1 依赖注入最佳实践

// ✅ 推荐:构造器注入
@Service
public class UserService {
    private final UserDao userDao;
    private final EmailService emailService;

    // Spring 4.3+ 单构造器可省略 @Autowired
    public UserService(UserDao userDao, EmailService emailService) {
        this.userDao = userDao;
        this.emailService = emailService;
    }
}

// ❌ 不推荐:字段注入
@Service
public class UserService {
    @Autowired
    private UserDao userDao;  // 难以测试
}

8.2 Bean 作用域使用

// 1. Singleton(默认)- 单例
@Service
@Scope("singleton")
public class UserService {
    // 线程不安全:不要有状态字段
}

// 2. Prototype - 每次获取创建新实例
@Service
@Scope("prototype")
public class TaskProcessor {
    // 有状态 Bean 使用 prototype
}

// 3. Request - Web 请求范围
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserContext {
    private User currentUser;
}

// 4. Session - Web 会话范围
@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ShoppingCart {
    private List<Item> items;
}

8.3 事务管理最佳实践

// ✅ 推荐做法
@Service
public class OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private InventoryService inventoryService;

    // 1. 事务加在 Service 层
    @Transactional
    public void createOrder(Order order) {
        orderDao.save(order);
        inventoryService.decreaseStock(order.getProductId(), order.getQuantity());
    }

    // 2. 只读事务优化查询
    @Transactional(readOnly = true)
    public Order findOrder(Long id) {
        return orderDao.findById(id);
    }

    // 3. 指定回滚异常
    @Transactional(rollbackFor = Exception.class)
    public void processOrder(Order order) throws Exception {
        // 业务逻辑
    }
}

// ❌ 常见错误
@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    // 错误1:同类方法调用,事务失效
    public void createUser(User user) {
        saveUser(user);  // 直接调用,不走代理,事务失效
    }

    @Transactional
    public void saveUser(User user) {
        userDao.save(user);
    }

    // 错误2:非 public 方法,事务失效
    @Transactional
    protected void updateUser(User user) {  // 非 public
        userDao.update(user);
    }

    // 错误3:捕获异常不抛出,事务不回滚
    @Transactional
    public void deleteUser(Long id) {
        try {
            userDao.delete(id);
        } catch (Exception e) {
            e.printStackTrace();  // 吞掉异常,事务不回滚
        }
    }
}

8.4 配置管理最佳实践

// 1. 使用 @ConfigurationProperties(类型安全)
@ConfigurationProperties(prefix = "app")
@Component
@Data
public class AppProperties {
    private String name;
    private String version;
    private Database database;

    @Data
    public static class Database {
        private String url;
        private String username;
        private String password;
    }
}

// application.yml
app:
  name: MyApp
  version: 1.0.0
  database:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: password

// 2. 使用 @Value(简单值)
@Component
public class EmailService {

    @Value("${email.smtp.host}")
    private String smtpHost;

    @Value("${email.smtp.port:587}")  // 默认值
    private int smtpPort;
}

// 3. 多环境配置
// application-dev.yml
// application-test.yml
// application-prod.yml

// 激活配置:
// spring.profiles.active=prod

8.5 异常处理最佳实践

// 1. 全局异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
        ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage());
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGeneral(Exception ex) {
        ErrorResponse error = new ErrorResponse("INTERNAL_ERROR", "系统错误");
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
    }
}

// 2. 自定义业务异常
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}

// 3. Service 层抛出业务异常
@Service
public class UserService {
    public User findUser(Long id) {
        return userDao.findById(id)
            .orElseThrow(() -> new ResourceNotFoundException("用户不存在: " + id));
    }
}

8.6 性能优化建议

// 1. 延迟加载
@Configuration
public class AppConfig {

    @Bean
    @Lazy  // 延迟初始化
    public HeavyService heavyService() {
        return new HeavyService();
    }
}

// 2. 异步处理
@Service
public class EmailService {

    @Async  // 异步执行
    public void sendEmail(String to, String subject, String content) {
        // 发送邮件
    }
}

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("async-");
        executor.initialize();
        return executor;
    }
}

// 3. 缓存
@Service
public class UserService {

    @Cacheable(value = "users", key = "#id")
    public User findUser(Long id) {
        return userDao.findById(id);
    }

    @CacheEvict(value = "users", key = "#user.id")
    public User updateUser(User user) {
        return userDao.update(user);
    }
}

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("users");
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值