引言:Spring框架在企业级Java开发中的核心地位

Spring框架是Java企业级应用开发的事实标准,它通过依赖注入(DI)和面向切面编程(AOP)解决了企业开发中的核心痛点。根据2023年JetBrains开发者生态系统调查,Spring Boot在Java框架使用率中以67%的占比稳居第一,这充分证明了其在行业中的主导地位。

Spring框架的核心价值在于:

  • 解耦:通过IoC容器管理对象依赖关系,降低代码耦合度
  • 简化:提供大量样板代码的自动化处理,如事务管理、数据访问
  • 集成:无缝整合各种主流技术栈(MyBatis、Hibernate、Redis等)
  • 测试:提供强大的测试支持,包括Mock对象和测试切面

本文将从基础概念讲起,逐步深入到高级特性,最后通过实战案例展示如何解决企业级开发中的实际问题。

第一部分:Spring框架基础概念与核心原理

1.1 IoC容器与依赖注入原理

核心概念:IoC(Inversion of Control)控制反转,将对象的创建和管理权从程序员交给Spring容器。

依赖注入的三种方式

  1. 构造器注入(推荐):通过构造函数传递依赖
  2. Setter注入:通过setter方法注入依赖
  3. 字段注入:使用@Autowired直接注解字段(不推荐,不利于测试)

代码示例:三种依赖注入方式

// 1. 构造器注入(推荐)
@Service
public class OrderService {
    private final UserService userService;
    private final PaymentService paymentService;
    
    // 使用构造器注入,明确依赖关系
    public OrderService(UserService userService, PaymentService paymentService) {
        this.userService = userService;
        this.paymentService = paymentService;
    }
}

// 2. Setter注入
@Service
public class OrderService {
    private UserService userService;
    
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}

// 3. 字段注入(不推荐)
@Service
public class OrderService {
    @Autowired
    private UserService userService;
}

Bean的作用域(Scope)详解

Spring Bean支持多种作用域,每种都有特定的使用场景:

作用域 描述 使用场景
singleton 默认,每个容器中一个Bean实例 无状态服务类、工具类
prototype 每次请求创建新实例 有状态的Bean,避免线程安全问题
request 每个HTTP请求一个实例 Web应用中的请求级数据
session 每个HTTP会话一个实例 用户登录信息存储
global-session Portlet应用的全局会话 集群环境下的会话共享

Bean生命周期完整流程

Spring Bean的生命周期包含12个关键步骤,理解这些步骤对排查问题至关重要:

@Component
public class ComplexBean implements InitializingBean, DisposableBean {
    
    private String name;
    
    // 1. 构造器执行
    public ComplexBean() {
        System.out.println("1. 构造器执行");
    }
    
    // 2. 属性填充
    @Value("ComplexBean")
    public void setName(String name) {
        this.name = name;
        System.out.println("2. 属性填充");
    }
    
    // 3. BeanPostProcessor前置处理
    // 4. @PostConstruct注解方法执行
    @PostConstruct
    public void postConstruct() {
        System.out.println("4. @PostConstruct执行");
    }
    
    // 5. InitializingBean.afterPropertiesSet()
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("5. InitializingBean执行");
    }
    
    // 6. init-method指定的方法
    @PreDestroy
    public void preDestroy() {
        System.out.println("11. @PreDestroy执行");
    }
    
    // 7. BeanPostProcessor后置处理
    // 8. Bean就绪可用
    // 9. 使用中...
    // 10. 容器关闭
    // 11. DisposableBean.destroy()
    @Override
    public void destroy() throws Exception {
        System.out.println("12. DisposableBean执行");
    }
}

1.2 AOP面向切面编程深度解析

AOP是Spring框架的另一大核心,它解决了横切关注点(如日志、事务、安全)的代码重复问题。

AOP核心术语

  • Joinpoint:程序执行过程中的某个位置(如方法调用、异常抛出)
  • Pointcut:匹配Joinpoint的表达式
  • Advice:在Pointcut指定位置执行的具体逻辑
  • Aspect:切面 = Pointcut + Advice
  • Weaving:将切面应用到目标对象的过程

完整AOP示例:实现方法执行时间监控

// 1. 定义切面
@Aspect
@Component
public class PerformanceMonitorAspect {
    
    // 定义切点:所有Service层的方法
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceMethods() {}
    
    // 环绕通知:最强大的通知类型
    @Around("serviceMethods()")
    public Object monitorPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法签名
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        
        // 开始时间
        long start = System.currentTimeMillis();
        
        try {
            // 执行目标方法
            Object result = joinPoint.proceed();
            return result;
        } finally {
            // 计算执行时间
            long duration = System.currentTimeMillis() - start;
            
            // 记录日志
            if (duration > 1000) { // 超过1秒警告
                System.err.printf("[性能警告] %s.%s 执行耗时:%dms%n", 
                    className, methodName, duration);
            } else {
                System.out.printf("[性能信息] %s.%s 执行耗时:%dms%n", 
                    className, methodName, duration);
            }
        }
    }
    
    // 异常通知:记录异常信息
    @AfterThrowing(pointcut = "serviceMethods()", throwing = "ex")
    public void logException(JoinPoint joinPoint, Exception ex) {
        String methodName = joinPoint.getSignature().getName();
        System.err.printf("[异常记录] %s 方法抛出异常:%s%n", 
            methodName, ex.getMessage());
    }
}

// 2. 业务服务类(无需修改任何代码)
@Service
public class UserService {
    public void createUser() throws InterruptedException {
        Thread.sleep(500); // 模拟耗时操作
        System.out.println("用户创建成功");
    }
}

// 3. 测试类
@SpringBootApplication
public class AopDemoApplication implements CommandLineRunner {
    
    @Autowired
    private UserService userService;
    
    public static void main(String[] args) {
        SpringApplication.run(AopDemoApplication.class, args);
    }
    
    @Override
    public void run(String... args) throws Exception {
        userService.createUser();
    }
}

AOP实现原理:动态代理

Spring AOP默认使用JDK动态代理(基于接口)或CGLIB(基于类继承):

// JDK动态代理示例
public class JdkDynamicProxyDemo {
    
    interface UserService {
        void save();
    }
    
    static class UserServiceImpl implements UserService {
        @Override
        public void save() {
            System.out.println("保存用户");
        }
    }
    
    static class PerformanceHandler implements InvocationHandler {
        private final Object target;
        
        public PerformanceHandler(Object target) {
            this.target = target;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            long start = System.currentTimeMillis();
            Object result = method.invoke(target, args);
            System.out.println("耗时:" + (System.currentTimeMillis() - start) + "ms");
            return result;
        }
    }
    
    public static void main(String[] args) {
        UserService target = new UserServiceImpl();
        UserService proxy = (UserService) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            new Class[]{UserService.class},
            new PerformanceHandler(target)
        );
        
        proxy.save(); // 输出:保存用户 + 耗时
    }
}

第二部分:Spring Boot企业级开发实战

2.1 自动配置原理深度剖析

Spring Boot的”约定大于配置”理念通过自动配置实现,理解其原理是高级开发的必备技能。

自动配置工作流程

  1. @SpringBootApplication注解包含@EnableAutoConfiguration
  2. SpringFactoriesLoader加载META-INF/spring.factories
  3. 根据Conditional注解条件判断是否生效

自定义Starter实现

创建自定义Starter是封装通用功能的最佳实践:

// 1. 自定义配置属性
@ConfigurationProperties(prefix = "custom.email")
public class EmailProperties {
    private String host = "localhost";
    private int port = 25;
    private String username;
    private String password;
    private boolean enabled = true;
    
    // getters and setters
}

// 2. 自动配置类
@Configuration
@ConditionalOnClass(EmailService.class)
@ConditionalOnProperty(prefix = "custom.email", name = "enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties(EmailProperties.class)
public class EmailAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean // 当容器中没有该Bean时才创建
    public EmailService emailService(EmailProperties properties) {
        return new EmailService(properties);
    }
}

// 3. 业务服务类
public class EmailService {
    private final EmailProperties properties;
    
    public EmailService(EmailProperties properties) {
        this.properties = properties;
    }
    
    public void send(String to, String subject, String content) {
        System.out.printf("发送邮件到:%s, 主题:%s, 内容:%s%n", to, subject, content);
        // 实际实现会使用JavaMailSender
    }
}

// 4. resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.email.EmailAutoConfiguration

// 5. 使用方只需引入依赖即可自动配置
// application.yml
custom:
  email:
    host: smtp.example.com
    username: user
    password: pass

2.2 Spring Data JPA最佳实践

实体类设计规范

@Entity
@Table(name = "users", indexes = {
    @Index(name = "idx_email", columnList = "email", unique = true),
    @Index(name = "idx_status", columnList = "status")
})
@DynamicUpdate // 只更新修改的字段
@Where(clause = "deleted = false") // 逻辑删除过滤
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false, length = 100)
    private String username;
    
    @Column(nullable = false, length = 200, unique = true)
    private String email;
    
    @Column(nullable = false, length = 20)
    @Enumerated(EnumType.STRING)
    private UserStatus status = UserStatus.ACTIVE;
    
    @Column(nullable = false)
    private boolean deleted = false;
    
    @CreationTimestamp
    private LocalDateTime createdAt;
    
    @UpdateTimestamp
    private LocalDateTime updatedAt;
    
    // 关联关系
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Order> orders;
    
    // 枚举定义
    public enum UserStatus {
        ACTIVE, INACTIVE, BANNED
    }
}

Repository层最佳实践

@Repository
public interface UserRepository extends JpaRepository<User, Long>,
                                       JpaSpecificationExecutor<User> {
    
    // 1. 方法名查询:Spring Data JPA会自动解析
    Optional<User> findByEmail(String email);
    
    // 2. 使用@Query自定义JPQL
    @Query("SELECT u FROM User u WHERE u.email = :email AND u.status = :status")
    Optional<User> findByEmailAndStatus(@Param("email") String email, 
                                        @Param("status") User.UserStatus status);
    
    // 3. 原生SQL查询
    @Query(value = "SELECT * FROM users WHERE email = ?1", nativeQuery = true)
    Optional<User> findByEmailNative(String email);
    
    // 4. 分页查询
    @Query("SELECT u FROM User u WHERE u.username LIKE %:keyword%")
    Page<User> findByUsernameContaining(@Param("keyword") String keyword, Pageable pageable);
    
    // 5. 自定义查询返回DTO(避免返回实体类)
    @Query("SELECT new com.example.dto.UserSummary(u.id, u.username, u.email) " +
           "FROM User u WHERE u.status = :status")
    List<UserSummary> findUserSummariesByStatus(@Param("status") User.UserStatus status);
    
    // 6. 批量操作
    @Modifying
    @Query("UPDATE User u SET u.status = :status WHERE u.id IN :ids")
    int updateStatusByIds(@Param("ids") List<Long> ids, @Param("status") User.UserStatus status);
    
    // 7. 自定义方法名查询
    List<User> findByStatusAndCreatedAtBetween(User.UserStatus status, 
                                               LocalDateTime start, 
                                               LocalDateTime end);
    
    // 8. 使用EntityGraph解决N+1查询问题
    @EntityGraph(attributePaths = {"orders"})
    Optional<User> findUserWithOrdersById(Long id);
}

Service层实现与事务管理

@Service
@Transactional // 类级别事务管理
public class UserService {
    
    private final UserRepository userRepository;
    private final OrderRepository orderRepository;
    
    public UserService(UserRepository userRepository, OrderRepository orderRepository) {
        this.userRepository = userRepository;
        this.orderRepository = orderRepository;
    }
    
    // 事务传播行为:REQUIRED(默认)- 如果存在事务则加入,否则新建
    @Transactional(propagation = Propagation.REQUIRED, 
                   rollbackFor = Exception.class,
                   timeout = 30)
    public User createUserWithOrder(User user, Order order) {
        // 1. 保存用户
        User savedUser = userRepository.save(user);
        
        // 2. 设置关联
        order.setUser(savedUser);
        orderRepository.save(order);
        
        // 3. 发送事件(异步处理)
        // 事件会在事务提交后才发布,避免事务未提交就读取数据
        // applicationEventPublisher.publishEvent(new UserCreatedEvent(savedUser));
        
        return savedUser;
    }
    
    // 只读事务,提升性能
    @Transactional(readOnly = true)
    public Optional<User> findUserById(Long id) {
        return userRepository.findById(id);
    }
    
    // 事务传播:REQUIRES_NEW - 挂起当前事务,新建一个
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logAudit(Long userId, String action) {
        // 审计日志独立事务,即使主事务回滚,审计日志也会保存
        // auditLogRepository.save(new AuditLog(userId, action));
    }
    
    // 异常回滚示例
    @Transactional(rollbackFor = BusinessException.class)
    public void complexBusinessOperation() throws BusinessException {
        try {
            // 业务操作
            someBusinessLogic();
        } catch (BusinessException e) {
            // 记录日志但不回滚
            log.error("业务异常", e);
            throw e; // 重新抛出触发回滚
        } catch (Exception e) {
            // 其他异常不回滚
            log.error("系统异常", e);
            // 不抛出,事务正常提交
        }
    }
}

2.3 REST API设计与实现

Controller层规范

@RestController
@RequestMapping("/api/v1/users")
@Validated // 启用方法级别参数校验
public class UserController {
    
    private final UserService userService;
    
    public UserController(UserService userService) {
        this.userService = userService;
    }
    
    // 1. 创建用户 - POST 201 Created
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public ApiResult<UserDTO> createUser(@Valid @RequestBody CreateUserRequest request) {
        User user = convertToEntity(request);
        User savedUser = userService.createUser(user);
        return ApiResult.success(convertToDTO(savedUser));
    }
    
    // 2. 获取用户 - GET 200 OK
    @GetMapping("/{id}")
    public ApiResult<UserDTO> getUser(@PathVariable @Min(1) Long id) {
        return userService.findUserById(id)
                .map(user -> ApiResult.success(convertToDTO(user)))
                .orElseThrow(() -> new UserNotFoundException(id));
    }
    
    // 3. 分页查询 - GET 200 OK
    @GetMapping
    public ApiResult<PageResult<UserDTO>> listUsers(
            @RequestParam(defaultValue = "1") @Min(1) int page,
            @RequestParam(defaultValue = "10") @Min(1) @Max(100) int size,
            @RequestParam(required = false) String keyword) {
        
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by("createdAt").descending());
        Page<User> userPage = userService.searchUsers(keyword, pageable);
        
        PageResult<UserDTO> result = PageResult.of(
                userPage.map(this::convertToDTO)
        );
        return ApiResult.success(result);
    }
    
    // 4. 更新用户 - PUT 200 OK
    @PutMapping("/{id}")
    public ApiResult<UserDTO> updateUser(@PathVariable Long id, 
                                         @Valid @RequestBody UpdateUserRequest request) {
        User updatedUser = userService.updateUser(id, request);
        return ApiResult.success(convertToDTO(updatedUser));
    }
    
    // 5. 删除用户 - DELETE 204 No Content
    @DeleteMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
    }
    
    // 6. 批量操作 - POST 200 OK
    @PostMapping("/batch")
    public ApiResult<Void> batchCreate(@Valid @RequestBody List<CreateUserRequest> requests) {
        List<User> users = requests.stream()
                .map(this::convertToEntity)
                .collect(Collectors.toList());
        userService.batchCreate(users);
        return ApiResult.success();
    }
    
    // DTO转换方法
    private UserDTO convertToDTO(User user) {
        UserDTO dto = new UserDTO();
        dto.setId(user.getId());
        dto.setUsername(user.getUsername());
        dto.setEmail(user.getEmail());
        dto.setStatus(user.getStatus().name());
        dto.setCreatedAt(user.getCreatedAt());
        return dto;
    }
    
    private User convertToEntity(CreateUserRequest request) {
        User user = new User();
        user.setUsername(request.getUsername());
        user.setEmail(request.getEmail());
        return user;
    }
}

统一响应格式与异常处理

// 统一响应格式
public class ApiResult<T> {
    private boolean success;
    private String message;
    private T data;
    private long timestamp;
    
    private ApiResult(boolean success, String message, T data) {
        this.success = success;
        this.message = message;
        this.data =data;
        this.timestamp = System.currentTimeMillis();
    }
    
    public static <T> ApiResult<T> success(T data) {
        return new ApiResult<>(true, "操作成功", data);
    }
    
    public static <T> ApiResult<T> success() {
        return new ApiResult<>(true, "操作成功", null);
    }
    
    public static <T> ApiResult<T> error(String message) {
        return new ApiResult<>(false, message, null);
    }
    
    // getters
}

// 全局异常处理器
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult<Map<String, String>> handleValidationException(MethodArgumentNotValidException ex) {
        Map<String, String> errors = ex.getBindingResult().getFieldErrors().stream()
                .collect(Collectors.toMap(
                        FieldError::getField,
                        FieldError::getDefaultMessage
                ));
        return ApiResult.error("参数校验失败:" + errors);
    }
    
    @ExceptionHandler(UserNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ApiResult<Void> handleUserNotFound(UserNotFoundException ex) {
        return ApiResult.error(ex.getMessage());
    }
    
    @ExceptionHandler(BusinessException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult<Void> handleBusinessException(BusinessException ex) {
        return ApiResult.error(ex.getMessage());
    }
    
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ApiResult<Void> handleException(Exception ex) {
        log.error("系统异常", ex);
        return ApiResult.error("系统内部错误,请联系管理员");
    }
}

第三部分:企业级高级特性与性能优化

3.1 缓存抽象与Redis集成

Spring Cache基础使用

@Service
public class UserService {
    
    private final UserRepository userRepository;
    
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    // 缓存用户信息,key为方法参数id
    @Cacheable(value = "users", key = "#id")
    public User getUserById(Long id) {
        log.info("从数据库查询用户:{}", id);
        return userRepository.findById(id).orElse(null);
    }
    
    // 更新缓存
    @CachePut(value = "users", key = "#user.id")
    public User updateUser(User user) {
        return userRepository.save(user);
    }
    
    // 删除缓存
    @CacheEvict(value = "users", key = "#id")
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
    
    // 复杂缓存:条件缓存
    @Cacheable(value = "users", 
               key = "#id", 
               unless = "#result == null") // 结果为null不缓存
    public User getUserByIdWithCondition(Long id) {
        return userRepository.findById(id).orElse(null);
    }
    
    // 批量操作
    @Cacheable(value = "users", key = "#ids")
    public List<User> getUsersByIds(List<Long> ids) {
        return userRepository.findAllById(ids);
    }
}

Redis集成与配置

// 1. Redis配置类
@Configuration
public class RedisConfig {
    
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        
        // 使用Jackson序列化
        Jackson2JsonRedisSerializer<Object> serializer = 
            new Jackson2JsonRedisSerializer<>(Object.class);
        
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(om);
        
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        
        return template;
    }
    
    // 自定义缓存管理器
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10)) // 默认10分钟
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(
                    new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(
                    new GenericJackson2JsonRedisSerializer()));
        
        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
    }
}

// 2. 使用RedisTemplate直接操作
@Service
public class CacheService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    
    public CacheService(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    
    // 设置值
    public void set(String key, Object value, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, value, timeout, unit);
    }
    
    // 获取值
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }
    
    // Hash操作
    public void putHash(String key, String hashKey, Object value) {
        redisTemplate.opsForHash().put(key, hashKey, value);
    }
    
    public Object getHash(String key, String hashKey) {
        return redisTemplate.opsForHash().get(key, hashKey);
    }
    
    // 分布式锁实现
    public boolean tryLock(String key, long timeout, TimeUnit unit) {
        return redisTemplate.opsForValue()
                .setIfAbsent(key, "LOCK", timeout, unit);
    }
    
    public void unlock(String key) {
        redisTemplate.delete(key);
    }
}

3.2 异步处理与消息队列

@Async异步处理

@Service
public class AsyncService {
    
    private static final Logger log = LoggerFactory.getLogger(AsyncService.class);
    
    // 自定义线程池配置
    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("async-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
    
    // 异步方法
    @Async("taskExecutor")
    public void sendEmail(String to, String subject, String content) {
        log.info("开始发送邮件到:{}", to);
        try {
            // 模拟耗时操作
            Thread.sleep(2000);
            log.info("邮件发送成功:{}", to);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("邮件发送失败", e);
        }
    }
    
    // 带返回值的异步方法
    @Async("taskExecutor")
    public CompletableFuture<String> processOrderAsync(Long orderId) {
        log.info("异步处理订单:{}", orderId);
        try {
            Thread.sleep(1000);
            return CompletableFuture.completedFuture("订单" + orderId + "处理完成");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return CompletableFuture.completedFuture("订单" + orderId + "处理失败");
        }
    }
}

Spring事件驱动架构

// 1. 自定义事件
public class UserCreatedEvent extends ApplicationEvent {
    private final User user;
    
    public UserCreatedEvent(Object source, User user) {
        super(source);
        this.user = user;
    }
    
    public User getUser() {
        return user;
    }
}

// 2. 事件发布者
@Service
public class UserService {
    
    private final ApplicationEventPublisher eventPublisher;
    private final UserRepository userRepository;
    
    public UserService(ApplicationEventPublisher eventPublisher, 
                      UserRepository userRepository) {
        this.eventPublisher = eventPublisher;
        this.userRepository = userRepository;
    }
    
    @Transactional
    public void createUser(User user) {
        userRepository.save(user);
        // 发布事件(事务提交后才执行监听器)
        eventPublisher.publishEvent(new UserCreatedEvent(this, user));
    }
}

// 3. 事件监听器
@Component
public class UserEventListener {
    
    private static final Logger log = LoggerFactory.getLogger(UserEventListener.class);
    
    // 同步监听(默认)
    @EventListener
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void handleUserCreated(UserCreatedEvent event) {
        log.info("处理用户创建事件:{}", event.getUser().getId());
        // 发送欢迎邮件、记录审计日志等
    }
    
    // 异步监听
    @Async
    @EventListener
    public void handleUserCreatedAsync(UserCreatedEvent event) {
        log.info("异步处理用户创建事件:{}", event.getUser().getId());
        // 调用第三方API、发送通知等
    }
    
    // 条件监听
    @EventListener(condition = "#event.user.status == T(com.example.UserStatus).ACTIVE")
    public void handleActiveUserCreated(UserCreatedEvent event) {
        log.info("活跃用户创建事件:{}", event.getUser().getId());
    }
}

3.3 安全框架Spring Security集成

基础配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) // 启用方法级安全
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            // 禁用CSRF(JWT场景下)
            .csrf().disable()
            // 认证配置
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/auth/**").permitAll() // 公开接口
                .requestMatchers("/api/admin/**").hasRole("ADMIN") // 管理员接口
                .anyRequest().authenticated() // 其他需要认证
            )
            // JWT过滤器
            .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
            // 异常处理
            .exceptionHandling(ex -> ex
                .authenticationEntryPoint(new RestAuthenticationEntryPoint())
                .accessDeniedHandler(new RestAccessDeniedHandler())
            )
            // 会话管理(无状态)
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            );
        
        return http.build();
    }
    
    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter();
    }
    
    // 密码编码器
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    // 认证管理器
    @Bean
    public AuthenticationManager authenticationManager(
            UserDetailsService userDetailsService,
            PasswordEncoder passwordEncoder) {
        
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(passwordEncoder);
        
        return new ProviderManager(provider);
    }
}

// JWT认证过滤器
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                   HttpServletResponse response, 
                                   FilterChain filterChain) throws ServletException, IOException {
        
        String jwt = getJwtFromRequest(request);
        
        if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
            Authentication authentication = tokenProvider.getAuthentication(jwt);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        
        filterChain.doFilter(request, response);
    }
    
    private String getJwtFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
}

方法级安全控制

@Service
public class AdminService {
    
    // 只有ADMIN角色可以访问
    @PreAuthorize("hasRole('ADMIN')")
    public void deleteUser(Long id) {
        // 删除用户逻辑
    }
    
    // 拥有USER_DELETE权限或ADMIN角色
    @PreAuthorize("hasAuthority('USER_DELETE') or hasRole('ADMIN')")
    public void deleteUserWithPermission(Long id) {
        // 删除用户逻辑
    }
    
    // 参数级权限控制
    @PreAuthorize("@securityService.isOwner(#id)")
    public void updateProfile(Long id, UserProfile profile) {
        // 只能修改自己的资料
    }
    
    // 表达式返回值控制
    @PostAuthorize("returnObject.username == authentication.name or hasRole('ADMIN')")
    public User getUser(Long id) {
        // 返回用户信息
        return userRepository.findById(id).orElse(null);
    }
    
    // 过滤返回集合
    @PostFilter("filterObject.username == authentication.name or hasRole('ADMIN')")
    public List<User> listUsers() {
        return userRepository.findAll();
    }
    
    // 输入参数过滤
    @PreFilter("filterObject.username == authentication.name or hasRole('ADMIN')")
    public void updateUsers(List<User> users) {
        // 批量更新
    }
}

3.4 测试策略与最佳实践

单元测试

@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    
    @Mock
    private UserRepository userRepository;
    
    @Mock
    private OrderRepository orderRepository;
    
    @InjectMocks
    private UserService userService;
    
    @Test
    @DisplayName("创建用户成功")
    void createUserSuccess() {
        // Given
        User user = new User();
        user.setUsername("testuser");
        user.setEmail("test@example.com");
        
        when(userRepository.save(any(User.class))).thenReturn(user);
        
        // When
        User result = userService.createUser(user);
        
        // Then
        assertNotNull(result);
        assertEquals("testuser", result.getUsername());
        verify(userRepository, times(1)).save(user);
    }
    
    @Test
    @DisplayName("创建用户失败 - 邮箱重复")
    void createUserFailEmailExists() {
        // Given
        User user = new User();
        user.setEmail("existing@example.com");
        
        when(userRepository.findByEmail("existing@example.com"))
            .thenReturn(Optional.of(new User()));
        
        // When & Then
        assertThrows(BusinessException.class, () -> {
            userService.createUser(user);
        });
        
        verify(userRepository, never()).save(any());
    }
}

集成测试

@SpringBootTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Transactional // 测试后回滚
class UserServiceIntegrationTest {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private UserRepository userRepository;
    
    @Test
    @DisplayName("完整用户创建流程")
    void completeUserCreationFlow() {
        // Given
        User user = new User();
        user.setUsername("integration");
        user.setEmail("integration@test.com");
        
        // When
        User savedUser = userService.createUser(user);
        
        // Then
        assertNotNull(savedUser.getId());
        
        // 验证数据库
        User found = userRepository.findById(savedUser.getId()).orElse(null);
        assertNotNull(found);
        assertEquals("integration", found.getUsername());
    }
}

MockMvc Web层测试

@WebMvcTest(UserController.class)
class UserControllerTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @MockBean
    private UserService userService;
    
    @Test
    @DisplayName("GET /api/v1/users/1 - 成功")
    void getUserSuccess() throws Exception {
        // Given
        UserDTO userDTO = new UserDTO();
        userDTO.setId(1L);
        userDTO.setUsername("test");
        
        when(userService.findUserById(1L)).thenReturn(Optional.of(new User()));
        
        // When & Then
        mockMvc.perform(get("/api/v1/users/1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.success").value(true))
                .andExpect(jsonPath("$.data.username").value("test"));
    }
    
    @Test
    @DisplayName("POST /api/v1/users - 参数错误")
    void createUserInvalidParams() throws Exception {
        // Given
        CreateUserRequest request = new CreateUserRequest();
        request.setEmail("invalid-email");
        
        // When & Then
        mockMvc.perform(post("/api/v1/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content(new ObjectMapper().writeValueAsString(request)))
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.success").value(false));
    }
}

第四部分:企业级应用架构模式

4.1 分层架构设计

标准的企业级应用分层:

┌─────────────────────────────────────┐
│  Controller层(API接口层)           │
│  - 参数校验                          │
│  - 响应格式化                        │
│  - 简单的业务逻辑                    │
├─────────────────────────────────────┤
│  Service层(业务逻辑层)             │
│  - 核心业务逻辑                      │
│  - 事务管理                          │
│  - 权限控制                          │
├─────────────────────────────────────┤
│  Repository层(数据访问层)          │
│  - 数据库操作                        │
│  - ORM映射                          │
│  - 基础CRUD                         │
├─────────────────────────────────────┤
│  Domain层(领域模型层)              │
│  - 实体类定义                        │
│  - 业务规则                          │
│  - 领域服务                          │
└─────────────────────────────────────┘

4.2 领域驱动设计(DDD)在Spring中的实践

实体与值对象

// 领域实体(有唯一标识)
@Entity
public class Order {
    @Id
    private OrderId id;
    private CustomerId customerId;
    private OrderStatus status;
    private Money totalAmount;
    private LocalDateTime createdAt;
    
    // 聚合根方法
    public void addItem(Product product, int quantity) {
        if (status != OrderStatus.PENDING) {
            throw new IllegalStateException("只能修改待处理订单");
        }
        items.add(new OrderItem(product, quantity));
        recalculateTotal();
    }
    
    private void recalculateTotal() {
        this.totalAmount = items.stream()
            .map(OrderItem::getSubtotal)
            .reduce(Money.ZERO, Money::add);
    }
}

// 值对象(无标识,不可变)
public class Money {
    private final BigDecimal amount;
    private final Currency currency;
    
    public Money add(Money other) {
        if (!this.currency.equals(other.currency)) {
            throw new IllegalArgumentException("货币类型不匹配");
        }
        return new Money(this.amount.add(other.amount), currency);
    }
    
    // equals, hashCode, toString
}

// 聚合根
@Entity
public class Order extends AggregateRoot<OrderId> {
    // ... 聚合逻辑
}

防腐层(Anti-Corruption Layer)

// 外部系统接口适配器
@Component
public class PaymentGatewayAdapter {
    
    private final PaymentGatewayClient client;
    
    public PaymentResult processPayment(PaymentCommand command) {
        try {
            // 转换为外部系统格式
            ExternalPaymentRequest externalRequest = toExternalRequest(command);
            
            // 调用外部系统
            ExternalPaymentResponse externalResponse = client.pay(externalRequest);
            
            // 转换回领域模型
            return toDomainResult(externalResponse);
        } catch (ExternalSystemException e) {
            throw new PaymentException("支付失败", e);
        }
    }
    
    private ExternalPaymentRequest toExternalRequest(PaymentCommand command) {
        // 转换逻辑
        return new ExternalPaymentRequest();
    }
    
    private PaymentResult toDomainResult(ExternalPaymentResponse response) {
        // 转换逻辑
        return new PaymentResult();
    }
}

4.3 微服务架构集成

服务注册与发现(Eureka)

// 1. Eureka Server
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

// 2. Eureka Client配置
spring:
  application:
    name: user-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

// 3. 服务调用(RestTemplate + 负载均衡)
@Service
public class OrderServiceClient {
    
    private final RestTemplate restTemplate;
    
    public OrderServiceClient(RestTemplateBuilder builder) {
        this.restTemplate = builder.build();
    }
    
    public OrderDTO getOrder(Long orderId) {
        // user-service是服务名,由Eureka解析
        String url = "http://user-service/api/orders/{orderId}";
        return restTemplate.getForObject(url, OrderDTO.class, orderId);
    }
}

// 4. 负载均衡配置
@Bean
@LoadBalanced // 重要:启用负载均衡
public RestTemplate restTemplate() {
    return new RestTemplate();
}

API网关(Spring Cloud Gateway)

// Gateway配置
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=1
            - name: Retry
              args:
                retries: 3
                backoff:
                  firstBackoff: 50ms
                  maxBackoff: 500ms
            - name: RateLimit
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20

第五部分:企业级开发难题解决方案

5.1 数据库事务并发控制

乐观锁实现

@Entity
public class Product {
    @Id
    private Long id;
    
    private String name;
    
    private BigDecimal price;
    
    @Version // 乐观锁版本号
    private Integer version;
    
    // 库存扣减(乐观锁)
    public void deductStock(int quantity) {
        if (this.stock < quantity) {
            throw new InsufficientStockException("库存不足");
        }
        this.stock -= quantity;
    }
}

// Service层
@Service
public class ProductService {
    
    @Transactional
    public void deductStock(Long productId, int quantity) {
        Product product = productRepository.findById(productId)
            .orElseThrow(() -> new ProductNotFoundException(productId));
        
        product.deductStock(quantity);
        
        // 保存时会自动检查版本号
        // 如果版本号不匹配,会抛出OptimisticLockException
        productRepository.save(product);
    }
}

悲观锁实现

// Repository层
public interface ProductRepository extends JpaRepository<Product, Long> {
    
    // 使用SELECT FOR UPDATE进行悲观锁
    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query("SELECT p FROM Product p WHERE p.id = :id")
    Optional<Product> findByIdForUpdate(@Param("id") Long id);
}

// Service层
@Service
public class ProductService {
    
    @Transactional
    public void deductStock(Long productId, int quantity) {
        // 加悲观锁,其他事务必须等待
        Product product = productRepository.findByIdForUpdate(productId)
            .orElseThrow(() -> new ProductNotFoundException(productId));
        
        product.deductStock(quantity);
        productRepository.save(product);
    }
}

5.2 分布式锁实现

Redis分布式锁(Redisson)

@Component
public class DistributedLockService {
    
    @Autowired
    private RedissonClient redissonClient;
    
    /**
     * 执行带分布式锁的业务逻辑
     * @param lockKey 锁的key
     * @param waitTime 等待锁时间(毫秒)
     * @param leaseTime 锁持有时间(毫秒)
     * @param business 业务逻辑
     */
    public <T> T executeWithLock(String lockKey, long waitTime, long leaseTime, 
                                  Supplier<T> business) {
        RLock lock = redissonClient.getLock(lockKey);
        
        try {
            // 尝试加锁,最多等待waitTime,锁定leaseTime后自动释放
            if (lock.tryLock(waitTime, leaseTime, TimeUnit.MILLISECONDS)) {
                return business.get();
            } else {
                throw new LockAcquireException("获取分布式锁失败");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new LockAcquireException("获取锁被中断", e);
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
    
    // 使用示例
    @Service
    public class OrderService {
        
        @Autowired
        private DistributedLockService lockService;
        
        public void processOrder(Long orderId) {
            String lockKey = "order:process:" + orderId;
            
            lockService.executeWithLock(lockKey, 5000, 30000, () -> {
                // 只有获取锁的线程才能执行
                Order order = orderRepository.findById(orderId);
                if (order.getStatus() == OrderStatus.PENDING) {
                    // 处理订单逻辑
                    order.setStatus(OrderStatus.PROCESSING);
                    orderRepository.save(order);
                }
                return null;
            });
        }
    }
}

5.3 大数据量分库分表

ShardingSphere集成

// 1. Maven依赖
// sharding-jdbc-spring-boot-starter

// 2. 配置
spring:
  shardingsphere:
    datasource:
      names: ds0, ds1
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/db0
        username: root
        password: root
      ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/db1
        username: root
        password: root
    
    rules:
      sharding:
        tables:
          orders:
            actual-data-nodes: ds${0..1}.orders_${0..7}  # 2库8表
            table-strategy:
              standard:
                sharding-column: user_id
                sharding-algorithm-name: orders-inline
            database-strategy:
              standard:
                sharding-column: user_id
                sharding-algorithm-name: database-inline
        
        sharding-algorithms:
          database-inline:
            type: INLINE
            props:
              algorithm-expression: ds${user_id % 2}
          orders-inline:
            type: INLINE
            props:
              algorithm-expression: orders_${user_id % 8}

// 3. 使用(透明分片)
@Service
public class OrderService {
    
    @Autowired
    private OrderRepository orderRepository;
    
    public void createOrder(Order order) {
        // ShardingSphere会自动根据user_id路由到正确的库表
        orderRepository.save(order);
    }
    
    public List<Order> getUserOrders(Long userId) {
        // 自动路由到对应库表查询
        return orderRepository.findByUserId(userId);
    }
}

5.4 接口幂等性保障

幂等性实现方案

// 1. 幂等表设计
@Entity
@Table(indexes = @Index(name = "idx_business_key", columnList = "businessKey", unique = true))
public class IdempotentRecord {
    @Id
    private String id;
    private String businessKey; // 业务唯一标识
    private String status; // SUCCESS, FAILED
    private LocalDateTime createdAt;
}

// 2. 幂等性Service
@Service
public class IdempotentService {
    
    @Autowired
    private IdempotentRepository idempotentRepository;
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    /**
     * 执行幂等性业务
     * @param businessKey 业务唯一标识
     * @param business 业务逻辑
     */
    public <T> T executeIdempotent(String businessKey, Supplier<T> business) {
        // 方案1:Redis分布式锁 + 数据库幂等表(推荐)
        String lockKey = "idempotent:" + businessKey;
        
        // 先检查是否已执行
        Optional<IdempotentRecord> record = idempotentRepository.findByBusinessKey(businessKey);
        if (record.isPresent()) {
            if ("SUCCESS".equals(record.get().getStatus())) {
                // 已成功执行,直接返回结果(需要业务层支持返回结果)
                throw new IdempotentException("重复请求,已处理");
            } else {
                // 上次失败,可以重试
                return business.get();
            }
        }
        
        // 获取分布式锁
        RLock lock = redissonClient.getLock(lockKey);
        try {
            if (lock.tryLock(1000, 5000, TimeUnit.MILLISECONDS)) {
                // 双重检查
                record = idempotentRepository.findByBusinessKey(businessKey);
                if (record.isPresent()) {
                    throw new IdempotentException("重复请求");
                }
                
                // 创建幂等记录
                IdempotentRecord newRecord = new IdempotentRecord();
                newRecord.setBusinessKey(businessKey);
                newRecord.setStatus("PROCESSING");
                newRecord.setCreatedAt(LocalDateTime.now());
                idempotentRepository.save(newRecord);
                
                try {
                    // 执行业务
                    T result = business.get();
                    
                    // 更新为成功
                    newRecord.setStatus("SUCCESS");
                    idempotentRepository.save(newRecord);
                    
                    return result;
                } catch (Exception e) {
                    // 更新为失败(可选)
                    newRecord.setStatus("FAILED");
                    idempotentRepository.save(newRecord);
                    throw e;
                }
            }
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        
        throw new IdempotentException("获取幂等锁失败");
    }
}

// 3. 使用示例
@Service
public class PaymentService {
    
    @Autowired
    private IdempotentService idempotentService;
    
    public PaymentResult processPayment(PaymentRequest request) {
        // 业务唯一标识:支付单号
        String businessKey = request.getPaymentNo();
        
        return idempotentService.executeIdempotent(businessKey, () -> {
            // 实际支付逻辑
            return doProcessPayment(request);
        });
    }
}

5.5 系统监控与诊断

Spring Boot Actuator + Prometheus + Grafana

// 1. Maven依赖
// spring-boot-starter-actuator
// micrometer-registry-prometheus

// 2. 配置
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always
  metrics:
    export:
      prometheus:
        enabled: true
    tags:
      application: ${spring.application.name}

// 3. 自定义健康检查
@Component
public class DatabaseHealthIndicator implements HealthIndicator {
    
    @Autowired
    private DataSource dataSource;
    
    @Override
    public Health health() {
        try (Connection conn = dataSource.getConnection()) {
            conn.createStatement().execute("SELECT 1");
            return Health.up()
                    .withDetail("database", "MySQL")
                    .withDetail("version", conn.getMetaData().getDatabaseProductVersion())
                    .build();
        } catch (Exception e) {
            return Health.down()
                    .withDetail("error", e.getMessage())
                    .build();
        }
    }
}

// 4. 自定义指标
@Service
public class BusinessMetricsService {
    
    private final MeterRegistry meterRegistry;
    
    public BusinessMetricsService(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
    
    public void recordOrderCreated(double amount) {
        // 计数器
        meterRegistry.counter("orders.created", 
            "type", "online",
            "currency", "CNY").increment();
        
        // 计时器
        Timer timer = meterRegistry.timer("order.processing.time");
        timer.record(() -> {
            // 处理订单
        });
        
        // 仪表(Gauge)
        Gauge.builder("order.amount", () -> amount)
            .description("订单金额")
            .register(meterRegistry);
    }
}

应用性能监控(APM)

// 使用SkyWalking自动追踪(无需代码)
// 只需在JVM参数添加:
// -javaagent:/path/to/skywalking-agent.jar
// -Dskywalking.agent.service_name=user-service

// 或者使用Spring Cloud Sleuth + Zipkin
// 1. Maven依赖
// spring-cloud-starter-sleuth
// spring-cloud-starter-zipkin

// 2. 配置
spring:
  zipkin:
    base-url: http://localhost:9411
  sleuth:
    sampler:
      probability: 1.0 # 采样率100%

// 3. 日志自动注入TraceId
// 在日志中自动添加[TraceId,SpanId]前缀

第六部分:Spring框架高级特性

6.1 动态数据源切换

// 1. 动态数据源配置
@Configuration
public class DynamicDataSourceConfig {
    
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    @Bean
    public DataSource dynamicDataSource(DataSource masterDataSource, 
                                       DataSource slaveDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("master", masterDataSource);
        targetDataSources.put("slave", slaveDataSource);
        
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.setDefaultTargetDataSource(masterDataSource);
        return dynamicDataSource;
    }
}

// 2. 数据源上下文
public class DataSourceContextHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
    
    public static void setDataSource(String dataSource) {
        contextHolder.set(dataSource);
    }
    
    public static String getDataSource() {
        return contextHolder.get();
    }
    
    public static void clear() {
        contextHolder.remove();
    }
}

// 3. 动态数据源类
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataSource();
    }
}

// 4. AOP切换数据源
@Aspect
@Component
public class DataSourceAspect {
    
    @Before("@annotation(master)")
    public void beforeMaster(JoinPoint joinPoint, Master master) {
        DataSourceContextHolder.setDataSource("master");
    }
    
    @Before("@annotation(slave)")
    public void beforeSlave(JoinPoint joinPoint, Slave slave) {
        DataSourceContextHolder.setDataSource("slave");
    }
    
    @After("@annotation(master) || @annotation(slave)")
    public void after(JoinPoint joinPoint) {
        DataSourceContextHolder.clear();
    }
}

// 5. 自定义注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Master {}

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Slave {}

// 6. 使用示例
@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Master
    public void createUser(User user) {
        userRepository.save(user);
    }
    
    @Slave
    public User getUser(Long id) {
        return userRepository.findById(id).orElse(null);
    }
}

6.2 动态路由与规则引擎

// 1. 规则定义
public interface RoutingRule {
    boolean matches(RoutingContext context);
    String getTarget();
}

// 2. 上下文
public class RoutingContext {
    private String userId;
    private String region;
    private String deviceType;
    private Map<String, Object> attributes;
    
    // getters
}

// 3. 规则引擎
@Component
public class RoutingEngine {
    
    private final List<RoutingRule> rules;
    
    public RoutingEngine(List<RoutingRule> rules) {
        this.rules = rules;
    }
    
    public String route(RoutingContext context) {
        return rules.stream()
                .filter(rule -> rule.matches(context))
                .map(RoutingRule::getTarget)
                .findFirst()
                .orElse("default");
    }
}

// 4. 具体规则实现
@Component
@Order(1)
public class RegionRoutingRule implements RoutingRule {
    @Override
    public boolean matches(RoutingContext context) {
        return "CN".equals(context.getRegion());
    }
    
    @Override
    public String getTarget() {
        return "cn-datasource";
    }
}

@Component
@Order(2)
public class DefaultRoutingRule implements RoutingRule {
    @Override
    public boolean matches(RoutingContext context) {
        return true; // 总是匹配
    }
    
    @Override
    public String getTarget() {
        return "default-datasource";
    }
}

6.3 柔性事务与最终一致性

本地消息表实现最终一致性

// 1. 消息表实体
@Entity
@Table(name = "local_message")
public class LocalMessage {
    @Id
    private String id;
    private String businessKey;
    private String topic;
    private String payload;
    private String status; // PENDING, SENT, FAILED
    private int retryCount;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

// 2. 消息服务
@Service
public class LocalMessageService {
    
    @Autowired
    private LocalMessageRepository messageRepository;
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    @Transactional
    public void sendMessage(String businessKey, String topic, Object payload) {
        // 1. 保存消息到本地表(与业务在同一事务)
        LocalMessage message = new LocalMessage();
        message.setId(UUID.randomUUID().toString());
        message.setBusinessKey(businessKey);
        message.setTopic(topic);
        message.setPayload(toJson(payload));
        message.setStatus("PENDING");
        message.setRetryCount(0);
        messageRepository.save(message);
        
        // 2. 业务操作...
    }
    
    // 定时任务重试发送
    @Scheduled(fixedDelay = 30000)
    @Transactional
    public void retrySendFailedMessages() {
        List<LocalMessage> messages = messageRepository
                .findByStatusAndRetryCountLessThan("FAILED", 3, PageRequest.of(0, 100));
        
        for (LocalMessage message : messages) {
            try {
                rabbitTemplate.convertAndSend(message.getTopic(), message.getPayload());
                message.setStatus("SENT");
                messageRepository.save(message);
            } catch (Exception e) {
                message.setRetryCount(message.getRetryCount() + 1);
                if (message.getRetryCount() >= 3) {
                    message.setStatus("FAILED");
                    // 发送告警
                }
                messageRepository.save(message);
            }
        }
    }
}

第七部分:企业级开发最佳实践

7.1 代码规范与设计原则

SOLID原则在Spring中的应用

// S - 单一职责原则
// 坏例子:一个类做太多事
@Service
public class OrderService {
    public void createOrder() { /*...*/ }
    public void sendEmail() { /*...*/ } // ❌ 职责不单一
    public void calculateTax() { /*...*/ }
}

// 好例子:职责分离
@Service
public class OrderService {
    private final EmailService emailService;
    private final TaxCalculator taxCalculator;
    
    public void createOrder() {
        // 只负责订单创建
    }
}

// O - 开闭原则
// 使用抽象和扩展
public interface PaymentStrategy {
    void pay(Money amount);
}

@Service
public class AlipayStrategy implements PaymentStrategy {
    public void pay(Money amount) { /*...*/ }
}

@Service
public class WechatPayStrategy implements PaymentStrategy {
    public void pay(Money amount) { /*...*/ }
}

// L - 里氏替换原则
// 子类必须能替换父类
public abstract class Animal {
    public abstract void makeSound();
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("汪汪");
    }
}

// I - 接口隔离原则
// 接口要精简
public interface ReadableRepository<T> {
    T findById(Long id);
    List<T> findAll();
}

public interface WritableRepository<T> {
    T save(T entity);
    void delete(Long id);
}

// D - 依赖倒置原则
// 依赖抽象,不依赖具体实现
@Service
public class OrderService {
    private final PaymentStrategy paymentStrategy; // 抽象
    
    public OrderService(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
}

7.2 异常处理最佳实践

// 1. 异常分层
// 业务异常(可恢复)
public class BusinessException extends RuntimeException {
    private String errorCode;
    
    public BusinessException(String errorCode, String message) {
        super(message);
        this.errorCode = errorCode;
    }
}

// 系统异常(不可恢复)
public class SystemException extends RuntimeException {
    public SystemException(String message, Throwable cause) {
        super(message, cause);
    }
}

// 2. 异常处理原则
@Service
public class UserService {
    
    // ✅ 好:具体异常,明确意图
    public void createUser(User user) {
        if (userRepository.existsByEmail(user.getEmail())) {
            throw new BusinessException("USER_EMAIL_EXISTS", "邮箱已存在");
        }
        userRepository.save(user);
    }
    
    // ❌ 坏:过于宽泛的异常捕获
    public void badExample() {
        try {
            // 业务逻辑
        } catch (Exception e) {
            // 吞掉异常或打印日志后继续
            log.error("出错了", e);
            // 不推荐:隐藏了问题
        }
    }
    
    // ✅ 好:异常转换
    public User getUser(Long id) {
        try {
            return userRepository.findById(id).orElseThrow();
        } catch (Exception e) {
            throw new SystemException("查询用户失败", e);
        }
    }
}

7.3 日志规范

// 1. 日志级别使用
@Service
public class OrderService {
    
    private static final Logger log = LoggerFactory.getLogger(OrderService.class);
    
    public void processOrder(Order order) {
        // TRACE: 极其详细的调试信息(通常不开启)
        log.trace("进入processOrder方法,order={}", order);
        
        // DEBUG: 开发调试信息
        log.debug("订单{}状态:{}", order.getId(), order.getStatus());
        
        // INFO: 重要业务节点(生产环境开启)
        log.info("开始处理订单:{}", order.getId());
        
        // WARN: 潜在问题警告
        if (order.getAmount().compareTo(BigDecimal.ZERO) < 0) {
            log.warn("订单金额异常:{}", order.getAmount());
        }
        
        // ERROR: 错误信息
        try {
            // 业务逻辑
        } catch (Exception e) {
            log.error("订单{}处理失败", order.getId(), e);
            throw e;
        }
    }
}

// 2. 日志格式规范
// 正确:使用参数化日志
log.info("用户{}创建订单{},金额:{}", userId, orderId, amount);

// 错误:字符串拼接
log.info("用户" + userId + "创建订单" + orderId); // ❌ 性能差

7.4 配置管理最佳实践

# 1. 配置文件组织
# application.yml (基础配置)
spring:
  application:
    name: user-service
  profiles:
    active: dev

# application-dev.yml (开发环境)
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/dev_db
    username: dev_user
    password: dev_pass

# application-prod.yml (生产环境)
spring:
  datasource:
    url: jdbc:mysql://db.prod.com:3306/prod_db
    username: ${DB_USER}
    password: ${DB_PASSWORD}

# 2. 配置属性类
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private final Cache cache = new Cache();
    private final Email email = new Email();
    
    public static class Cache {
        private boolean enabled = true;
        private Duration ttl = Duration.ofMinutes(10);
        // getters/setters
    }
    
    public static class Email {
        private String host;
        private int port;
        // getters/setters
    }
}

// 3. 敏感信息加密
// 使用Jasypt加密
// 1. Maven依赖:jasypt-spring-boot-starter
// 2. 配置加密密钥
jasypt:
  encryptor:
    password: ${JASYPT_PASSWORD}
// 3. 加密密码
// ENC(加密后的字符串)
spring:
  datasource:
    password: ENC(xxxxxxxx)

第八部分:实战案例 - 电商系统开发

8.1 需求分析与架构设计

需求:实现一个支持高并发的电商订单系统

核心功能

  • 商品管理
  • 购物车
  • 订单创建
  • 库存扣减
  • 支付处理
  • 分布式锁防止超卖

8.2 完整代码实现

// 1. 领域模型
@Entity
public class Product {
    @Id
    private Long id;
    private String name;
    private BigDecimal price;
    private Integer stock;
    @Version
    private Integer version;
    
    public void deductStock(int quantity) {
        if (stock < quantity) {
            throw new InsufficientStockException("库存不足");
        }
        stock -= quantity;
    }
}

@Entity
public class Order {
    @Id
    private Long id;
    private String orderNo;
    private Long userId;
    private BigDecimal amount;
    private OrderStatus status;
    @OneToMany(cascade = CascadeType.ALL)
    private List<OrderItem> items;
}

// 2. Repository层
public interface ProductRepository extends JpaRepository<Product, Long> {
    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query("SELECT p FROM Product p WHERE p.id = :id")
    Optional<Product> findByIdForUpdate(@Param("id") Long id);
}

public interface OrderRepository extends JpaRepository<Order, Long> {
    Optional<Order> findByOrderNo(String orderNo);
}

// 3. Service层
@Service
@Transactional
public class OrderService {
    
    private final ProductRepository productRepository;
    private final OrderRepository orderRepository;
    private final RedisTemplate<String, Object> redisTemplate;
    private final ApplicationEventPublisher eventPublisher;
    
    public OrderService(ProductRepository productRepository,
                       OrderRepository orderRepository,
                       RedisTemplate<String, Object> redisTemplate,
                       ApplicationEventPublisher eventPublisher) {
        this.productRepository = productRepository;
        this.orderRepository = orderRepository;
        this.redisTemplate = redisTemplate;
        this.eventPublisher = eventPublisher;
    }
    
    public Order createOrder(Long userId, List<OrderItemRequest> items) {
        // 1. 生成订单号(分布式ID)
        String orderNo = generateOrderNo();
        
        // 2. 计算总金额并扣减库存(使用悲观锁)
        BigDecimal totalAmount = BigDecimal.ZERO;
        List<OrderItem> orderItems = new ArrayList<>();
        
        for (OrderItemRequest itemRequest : items) {
            // 获取分布式锁防止超卖
            String lockKey = "product:stock:" + itemRequest.getProductId();
            RLock lock = redissonClient.getLock(lockKey);
            
            try {
                if (!lock.tryLock(3000, 10000, TimeUnit.MILLISECONDS)) {
                    throw new LockAcquireException("商品抢购太频繁,请稍后重试");
                }
                
                // 悲观锁查询并扣减库存
                Product product = productRepository.findByIdForUpdate(itemRequest.getProductId())
                    .orElseThrow(() -> new ProductNotFoundException(itemRequest.getProductId()));
                
                product.deductStock(itemRequest.getQuantity());
                productRepository.save(product);
                
                // 累加金额
                BigDecimal itemTotal = product.getPrice().multiply(
                    new BigDecimal(itemRequest.getQuantity()));
                totalAmount = totalAmount.add(itemTotal);
                
                // 创建订单项
                OrderItem orderItem = new OrderItem();
                orderItem.setProductId(product.getId());
                orderItem.setProductName(product.getName());
                orderItem.setQuantity(itemRequest.getQuantity());
                orderItem.setUnitPrice(product.getPrice());
                orderItems.add(orderItem);
                
            } finally {
                if (lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
        }
        
        // 3. 创建订单
        Order order = new Order();
        order.setOrderNo(orderNo);
        order.setUserId(userId);
        order.setAmount(totalAmount);
        order.setStatus(OrderStatus.PENDING);
        order.setItems(orderItems);
        
        Order savedOrder = orderRepository.save(order);
        
        // 4. 发布订单创建事件(异步处理支付、通知等)
        eventPublisher.publishEvent(new OrderCreatedEvent(this, savedOrder));
        
        return savedOrder;
    }
    
    private String generateOrderNo() {
        // 基于Redis的分布式ID生成器
        String key = "order:no:seq";
        Long seq = redisTemplate.opsForValue().increment(key);
        return "ORD" + System.currentTimeMillis() + String.format("%06d", seq);
    }
}

// 4. 事件监听器
@Component
public class OrderEventListener {
    
    @Async
    @EventListener
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void handleOrderCreated(OrderCreatedEvent event) {
        Order order = event.getOrder();
        
        // 1. 发送支付请求(异步)
        // paymentService.requestPayment(order);
        
        // 2. 发送通知(异步)
        // notificationService.sendOrderCreatedNotification(order);
        
        // 3. 记录审计日志
        log.info("订单创建事件处理完成:{}", order.getOrderNo());
    }
}

// 5. Controller层
@RestController
@RequestMapping("/api/orders")
public class OrderController {
    
    private final OrderService orderService;
    
    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }
    
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public ApiResult<OrderDTO> createOrder(@Valid @RequestBody CreateOrderRequest request,
                                          @AuthenticationPrincipal UserDetails userDetails) {
        Long userId = Long.parseLong(userDetails.getUsername());
        Order order = orderService.createOrder(userId, request.getItems());
        return ApiResult.success(convertToDTO(order));
    }
}

8.3 性能优化点

  1. 库存扣减:使用Redis分布式锁 + 悲观锁,防止超卖
  2. 订单号生成:基于Redis原子递增,避免数据库压力
  3. 异步处理:订单创建后异步处理支付和通知,提升响应速度
  4. 缓存:商品信息缓存到Redis,减少数据库查询

8.4 测试验证

@SpringBootTest
@Transactional
class OrderServiceIntegrationTest {
    
    @Autowired
    private OrderService orderService;
    
    @Autowired
    private ProductRepository productRepository;
    
    @Test
    @DisplayName("并发下单测试 - 防止超卖")
    void concurrentOrderTest() throws InterruptedException {
        // 准备商品:库存10
        Product product = new Product();
        product.setId(1L);
        product.setName("iPhone 15");
        product.setPrice(new BigDecimal("5999"));
        product.setStock(10);
        productRepository.save(product);
        
        // 模拟100个线程同时下单,每个线程购买1个
        int threadCount = 100;
        CountDownLatch startLatch = new CountDownLatch(1);
        CountDownLatch endLatch = new CountDownLatch(threadCount);
        AtomicInteger successCount = new AtomicInteger(0);
        AtomicInteger failCount = new AtomicInteger(0);
        
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                try {
                    startLatch.await(); // 等待开始信号
                    orderService.createOrder(1L, Arrays.asList(
                        new OrderItemRequest(1L, 1)
                    ));
                    successCount.incrementAndGet();
                } catch (Exception e) {
                    failCount.incrementAndGet();
                } finally {
                    endLatch.countDown();
                }
            }).start();
        }
        
        // 统一启动
        startLatch.countDown();
        endLatch.await();
        
        // 验证:只有10个成功,90个失败
        assertEquals(10, successCount.get());
        assertEquals(90, failCount.get());
        
        // 验证库存:0
        Product finalProduct = productRepository.findById(1L).orElse(null);
        assertEquals(0, finalProduct.getStock());
    }
}

第九部分:持续学习与进阶路线

9.1 Spring生态体系

Spring Framework Core
    ├── IoC容器
    ├── AOP
    ├── 数据访问
    └── 事务管理

Spring Boot
    ├── 自动配置
    ├── 嵌入式服务器
    ├── Actuator
    └── Starter

Spring Cloud
    ├── Eureka(服务发现)
    ├── Ribbon(负载均衡)
    ├── Hystrix(熔断器)
    ├── Gateway(网关)
    └── Config(配置中心)

Spring Data
    ├── JPA
    ├── MongoDB
    ├── Redis
    └── Elasticsearch

Spring Security
    ├── 认证
    ├── 授权
    ├── OAuth2
    └── JWT

Spring Batch(批处理)
Spring Integration(集成)
Spring WebSocket(实时通信)

9.2 推荐学习路径

  1. 基础阶段(1-2个月)

    • 掌握Spring Core和IoC/AOP原理
    • 熟练使用Spring Boot开发Web应用
    • 理解Spring Data JPA
  2. 进阶阶段(2-3个月)

    • 深入Spring Security
    • 掌握Spring Cloud微服务
    • 学习缓存、消息队列集成
  3. 高级阶段(持续)

    • 阅读Spring源码
    • 理解设计模式在Spring中的应用
    • 掌握性能调优和故障排查

9.3 推荐资源

  • 官方文档:spring.io/projects/spring-framework
  • 书籍:《Spring实战》、《Spring Boot编程思想》
  • 源码:GitHub spring-projects/spring-framework
  • 社区:Spring官方论坛、Stack Overflow

总结

Spring框架作为Java企业级开发的基石,其价值不仅在于提供强大的功能,更在于其优秀的架构设计和扩展性。通过本文的学习,你应该能够:

  1. 理解核心原理:IoC、AOP、自动配置等底层机制
  2. 掌握实战技巧:数据访问、事务管理、安全控制等
  3. 解决企业难题:并发控制、分布式锁、性能优化等
  4. 遵循最佳实践:代码规范、异常处理、日志规范等

记住,Spring框架的学习是一个持续的过程。建议在实际项目中不断实践,遇到问题时查阅官方文档和源码,逐步形成自己的技术体系。同时,关注Spring生态的最新发展,如Spring Native、Spring GraphQL等新技术,保持技术的先进性。

最后,技术只是工具,真正的价值在于解决业务问题。在使用Spring框架时,始终要思考如何更好地支撑业务发展,如何提升系统质量,如何为用户创造价值。这才是成为一名优秀Java开发者的根本。