引言

Spring框架是Java企业级应用开发的事实标准,它提供了全面的编程和配置模型,为现代Java应用开发提供了强大的支持。从简单的独立应用到复杂的分布式系统,Spring都能提供优雅的解决方案。本文将为初学者提供一个从零基础到实战应用的完整学习路径,帮助您系统地掌握Spring框架。

第一部分:基础准备阶段

1.1 Java基础要求

在学习Spring之前,您需要具备扎实的Java基础:

  • 面向对象编程:理解类、对象、继承、多态、封装等概念
  • 集合框架:熟悉List、Set、Map等常用集合类
  • 异常处理:掌握try-catch-finally和自定义异常
  • IO流:了解文件读写操作
  • 多线程基础:了解线程的基本概念和使用

示例代码:一个简单的Java类定义

// 基础的Java类示例
public class Student {
    private String name;
    private int age;
    
    // 构造方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // getter和setter方法
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    // 业务方法
    public void study() {
        System.out.println(name + "正在学习...");
    }
}

1.2 开发环境搭建

推荐工具

  • IDE:IntelliJ IDEA(推荐)或Eclipse
  • 构建工具:Maven或Gradle(推荐Maven)
  • JDK:JDK 8或更高版本(推荐JDK 11或17)
  • 数据库:MySQL(推荐)或H2(用于测试)

Maven项目结构

my-spring-app/
├── pom.xml
└── src/
    ├── main/
    │   ├── java/
    │   │   └── com/example/
    │   └── resources/
    └── test/
        ├── java/
        └── resources/

第二部分:Spring核心概念

2.1 Spring框架概述

Spring是一个分层架构,主要包含以下模块:

  • Spring Core:核心容器,提供IoC和DI功能
  • Spring AOP:面向切面编程
  • Spring MVC:Web框架
  • Spring Data:数据访问抽象
  • Spring Security:安全框架
  • Spring Boot:快速开发工具

2.2 控制反转(IoC)与依赖注入(DI)

IoC(Inversion of Control):将对象的创建和管理权交给Spring容器,而不是由应用程序自己创建。

DI(Dependency Injection):Spring容器通过构造器、setter方法或字段注入的方式,为对象提供所需的依赖。

示例代码:传统方式 vs Spring方式

// 传统方式 - 紧耦合
public class UserService {
    private UserRepository userRepository = new UserRepository(); // 直接创建依赖
    
    public void saveUser(User user) {
        userRepository.save(user);
    }
}

// Spring方式 - 松耦合
public class UserService {
    private UserRepository userRepository;
    
    // 通过构造器注入依赖
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public void saveUser(User user) {
        userRepository.save(user);
    }
}

2.3 Spring Bean管理

Bean定义方式

  1. XML配置(传统方式)
  2. 注解方式(推荐)
  3. Java配置类(推荐)

示例代码:三种Bean定义方式

// 1. XML配置方式(applicationContext.xml)
// <bean id="userService" class="com.example.service.UserService"/>

// 2. 注解方式
@Service
public class UserService {
    // ...
}

// 3. Java配置类方式
@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService();
    }
}

第三部分:Spring Boot快速入门

3.1 Spring Boot简介

Spring Boot是Spring框架的扩展,它:

  • 简化了Spring应用的配置
  • 提供了自动配置功能
  • 内嵌了Tomcat等Web服务器
  • 提供了生产级监控功能

3.2 创建第一个Spring Boot应用

使用Spring Initializr创建项目

  1. 访问 https://start.spring.io/
  2. 选择项目元数据(Group、Artifact)
  3. 添加依赖:Spring Web
  4. 生成项目并下载

项目结构

my-spring-boot-app/
├── pom.xml
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/example/demo/
│   │   │       ├── DemoApplication.java  // 主启动类
│   │   │       └── controller/
│   │   └── resources/
│   │       ├── static/
│   │       ├── templates/
│   │       └── application.properties
│   └── test/
│       └── java/

示例代码:Hello World应用

// 主启动类
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

// 控制器类
@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello, Spring Boot!";
    }
}

3.3 Spring Boot自动配置原理

Spring Boot通过@SpringBootApplication注解实现自动配置:

  • @SpringBootApplication = @Configuration + @ComponentScan + @EnableAutoConfiguration

自动配置流程

  1. Spring Boot启动时,加载META-INF/spring.factories文件
  2. 找到org.springframework.boot.autoconfigure.EnableAutoConfiguration配置的类
  3. 根据条件(@Conditional)决定是否启用自动配置

示例代码:自定义自动配置

// 1. 创建配置属性类
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
    private String name;
    private String version;
    // getters and setters
}

// 2. 创建自动配置类
@Configuration
@EnableConfigurationProperties(MyAppProperties.class)
@ConditionalOnClass(MyService.class)
public class MyAppAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public MyService myService(MyAppProperties properties) {
        return new MyService(properties.getName());
    }
}

// 3. 在META-INF/spring.factories中注册
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAppAutoConfiguration

第四部分:Spring Web开发

4.1 Spring MVC基础

Spring MVC是基于Servlet API的Web框架,核心组件:

  • DispatcherServlet:前端控制器
  • HandlerMapping:处理器映射
  • HandlerAdapter:处理器适配器
  • ViewResolver:视图解析器

请求处理流程

浏览器请求 → DispatcherServlet → HandlerMapping → HandlerAdapter → Controller → Model → ViewResolver → View → 响应

4.2 RESTful API开发

示例代码:完整的RESTful API示例

// 实体类
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    // getters and setters
}

// Repository接口
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);
}

// Service层
@Service
@Transactional
public class UserService {
    private final UserRepository userRepository;
    
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public User createUser(User user) {
        if (userRepository.findByEmail(user.getEmail()).isPresent()) {
            throw new RuntimeException("Email already exists");
        }
        return userRepository.save(user);
    }
    
    public Optional<User> getUserById(Long id) {
        return userRepository.findById(id);
    }
    
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
    
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}

// Controller层
@RestController
@RequestMapping("/api/users")
public class UserController {
    private final UserService userService;
    
    public UserController(UserService userService) {
        this.userService = userService;
    }
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User createdUser = userService.createUser(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        return userService.getUserById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }
    
    @GetMapping
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}

4.3 请求参数处理

示例代码:各种参数处理方式

@RestController
@RequestMapping("/api/demo")
public class DemoController {
    
    // 1. 路径参数
    @GetMapping("/path/{id}")
    public String pathParam(@PathVariable Long id) {
        return "Path param: " + id;
    }
    
    // 2. 查询参数
    @GetMapping("/query")
    public String queryParam(@RequestParam String name, @RequestParam(defaultValue = "10") int age) {
        return String.format("Query params: name=%s, age=%d", name, age);
    }
    
    // 3. 表单参数
    @PostMapping("/form")
    public String formParam(@RequestParam String username, @RequestParam String password) {
        return String.format("Form params: username=%s, password=%s", username, password);
    }
    
    // 4. JSON请求体
    @PostMapping("/json")
    public String jsonBody(@RequestBody User user) {
        return "JSON body: " + user.getName();
    }
    
    // 5. 请求头
    @GetMapping("/header")
    public String header(@RequestHeader("Authorization") String token) {
        return "Header token: " + token;
    }
    
    // 6. Cookie
    @GetMapping("/cookie")
    public String cookie(@CookieValue("sessionId") String sessionId) {
        return "Cookie sessionId: " + sessionId;
    }
}

第五部分:Spring Data JPA

5.1 JPA与Hibernate

JPA(Java Persistence API)是Java持久化规范,Hibernate是其实现。Spring Data JPA在此基础上提供了更简洁的Repository抽象。

5.2 Repository接口

示例代码:Repository接口定义

// 1. 基本Repository接口
public interface UserRepository extends JpaRepository<User, Long> {
    
    // 自定义查询方法
    List<User> findByName(String name);
    
    // 使用JPQL查询
    @Query("SELECT u FROM User u WHERE u.email = :email")
    Optional<User> findByEmail(@Param("email") String email);
    
    // 使用原生SQL查询
    @Query(value = "SELECT * FROM users WHERE age > :age", nativeQuery = true)
    List<User> findUsersByAgeGreaterThan(@Param("age") int age);
    
    // 分页查询
    Page<User> findByAgeGreaterThan(int age, Pageable pageable);
    
    // 排序查询
    List<User> findByAgeGreaterThan(int age, Sort sort);
    
    // 自定义更新操作
    @Modifying
    @Query("UPDATE User u SET u.name = :name WHERE u.id = :id")
    int updateUserName(@Param("id") Long id, @Param("name") String name);
}

// 2. 复杂查询示例
public interface UserRepository extends JpaRepository<User, Long> {
    
    // 使用Specification进行动态查询
    List<User> findAll(Specification<User> specification);
    
    // 使用QueryDSL(需要额外依赖)
    // List<User> findAll(QUser user, Predicate predicate);
}

// 3. 自定义Repository实现
public interface CustomUserRepository {
    List<User> findUsersWithComplexCriteria();
}

public class CustomUserRepositoryImpl implements CustomUserRepository {
    
    @PersistenceContext
    private EntityManager entityManager;
    
    @Override
    public List<User> findUsersWithComplexCriteria() {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<User> query = cb.createQuery(User.class);
        Root<User> root = query.from(User.class);
        
        // 构建复杂查询条件
        Predicate condition = cb.and(
            cb.greaterThan(root.get("age"), 18),
            cb.isNotNull(root.get("email"))
        );
        
        query.where(condition);
        query.orderBy(cb.desc(root.get("createdAt")));
        
        return entityManager.createQuery(query).getResultList();
    }
}

5.3 事务管理

示例代码:事务管理示例

@Service
@Transactional
public class UserService {
    
    private final UserRepository userRepository;
    private final OrderService orderService;
    
    public UserService(UserRepository userRepository, OrderService orderService) {
        this.userRepository = userRepository;
        this.orderService = orderService;
    }
    
    // 事务传播行为
    @Transactional(propagation = Propagation.REQUIRED)
    public void createUserWithOrder(User user, Order order) {
        userRepository.save(user);
        orderService.createOrder(order); // 同一个事务
    }
    
    // 事务隔离级别
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public User getUserForUpdate(Long id) {
        return userRepository.findById(id).orElseThrow();
    }
    
    // 回滚规则
    @Transactional(rollbackFor = Exception.class)
    public void processWithRollback() throws Exception {
        // 业务逻辑
        if (someCondition) {
            throw new CustomException("业务异常");
        }
    }
    
    // 只读事务
    @Transactional(readOnly = true)
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
}

第六部分:Spring Security

6.1 安全基础

Spring Security提供了全面的安全解决方案,包括:

  • 认证(Authentication)
  • 授权(Authorization)
  • 防止常见攻击(CSRF、Session固定等)

6.2 基本配置

示例代码:Spring Security配置

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable() // 禁用CSRF(对于REST API)
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .requestMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin() // 表单登录
                .loginPage("/login")
                .defaultSuccessUrl("/home")
                .permitAll()
            .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout")
                .permitAll()
            .httpBasic(); // HTTP Basic认证
        
        return http.build();
    }
    
    @Bean
    public UserDetailsService userDetailsService() {
        // 内存用户存储
        UserDetails user = User.builder()
            .username("user")
            .password(passwordEncoder().encode("password"))
            .roles("USER")
            .build();
        
        UserDetails admin = User.builder()
            .username("admin")
            .password(passwordEncoder().encode("admin"))
            .roles("ADMIN", "USER")
            .build();
        
        return new InMemoryUserDetailsManager(user, admin);
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

6.3 JWT认证实现

示例代码:JWT认证实现

// JWT工具类
@Component
public class JwtUtil {
    
    private static final String SECRET_KEY = "your-secret-key";
    private static final long EXPIRATION_TIME = 86400000; // 24小时
    
    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("roles", userDetails.getAuthorities().stream()
            .map(GrantedAuthority::getAuthority)
            .collect(Collectors.toList()));
        
        return Jwts.builder()
            .setClaims(claims)
            .setSubject(userDetails.getUsername())
            .setIssuedAt(new Date())
            .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
            .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
            .compact();
    }
    
    public Claims extractAllClaims(String token) {
        return Jwts.parser()
            .setSigningKey(SECRET_KEY)
            .parseClaimsJws(token)
            .getBody();
    }
    
    public String extractUsername(String token) {
        return extractAllClaims(token).getSubject();
    }
    
    public boolean isTokenExpired(String token) {
        return extractAllClaims(token).getExpiration().before(new Date());
    }
    
    public boolean validateToken(String token, UserDetails userDetails) {
        final String username = extractUsername(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }
}

// JWT认证过滤器
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
    
    @Autowired
    private UserDetailsService userDetailsService;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                   HttpServletResponse response, 
                                   FilterChain filterChain) throws ServletException, IOException {
        
        final String authorizationHeader = request.getHeader("Authorization");
        
        String username = null;
        String jwt = null;
        
        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            jwt = authorizationHeader.substring(7);
            username = jwtUtil.extractUsername(jwt);
        }
        
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
            
            if (jwtUtil.validateToken(jwt, userDetails)) {
                UsernamePasswordAuthenticationToken authenticationToken = 
                    new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }
        
        filterChain.doFilter(request, response);
    }
}

// 更新Security配置
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Autowired
    private JwtRequestFilter jwtRequestFilter;
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/auth/**").permitAll()
                .anyRequest().authenticated()
            )
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            );
        
        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        
        return http.build();
    }
    
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

第七部分:Spring Cloud微服务

7.1 微服务架构概述

微服务架构将单体应用拆分为多个小型服务,每个服务独立部署、独立扩展。

7.2 Spring Cloud核心组件

示例代码:微服务项目结构

microservices/
├── service-registry/      # Eureka服务注册中心
├── config-server/         # 配置中心
├── api-gateway/           # API网关
├── user-service/          # 用户服务
├── order-service/         # 订单服务
└── product-service/       # 产品服务

7.3 服务注册与发现(Eureka)

示例代码:Eureka服务注册中心

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

// application.yml配置
server:
  port: 8761

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:8761/eureka/

示例代码:Eureka Client(服务提供者)

// 2. Eureka Client (服务提供者)
@SpringBootApplication
@EnableEurekaClient
@RestController
public class UserServiceApplication {
    
    @Value("${server.port}")
    private int port;
    
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return new User(id, "User-" + id, "user" + id + "@example.com");
    }
    
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

// application.yml配置
server:
  port: 8081

spring:
  application:
    name: user-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

7.4 API网关(Spring Cloud Gateway)

示例代码:API网关配置

// 1. 网关主类
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

// 2. 路由配置(application.yml)
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20
                key-resolver: "#{@userKeyResolver}"
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=1

第八部分:Spring Boot高级特性

8.1 配置管理

示例代码:多环境配置

// application.yml(基础配置)
spring:
  profiles:
    active: dev

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

# application-prod.yml(生产环境)
server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://prod-db:3306/prod_db
    username: prod_user
    password: prod_pass
    hikari:
      maximum-pool-size: 20

8.2 监控与健康检查

示例代码:Actuator配置

// 1. 添加依赖
// pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

// 2. 配置application.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always
    metrics:
      export:
        prometheus:
          enabled: true

// 3. 自定义健康检查
@Component
public class CustomHealthIndicator implements HealthIndicator {
    
    @Override
    public Health health() {
        // 检查业务逻辑
        boolean isHealthy = checkBusinessLogic();
        
        if (isHealthy) {
            return Health.up()
                .withDetail("status", "业务正常")
                .withDetail("timestamp", System.currentTimeMillis())
                .build();
        } else {
            return Health.down()
                .withDetail("status", "业务异常")
                .withDetail("timestamp", System.currentTimeMillis())
                .build();
        }
    }
    
    private boolean checkBusinessLogic() {
        // 实际业务检查逻辑
        return true;
    }
}

8.3 异步处理

示例代码:异步任务处理

// 1. 启用异步支持
@Configuration
@EnableAsync
public class AsyncConfig {
    
    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("async-");
        executor.initialize();
        return executor;
    }
}

// 2. 异步服务
@Service
public class EmailService {
    
    @Async
    public CompletableFuture<String> sendEmail(String to, String subject, String body) {
        // 模拟发送邮件的耗时操作
        try {
            Thread.sleep(2000);
            System.out.println("邮件已发送到: " + to);
            return CompletableFuture.completedFuture("邮件发送成功");
        } catch (InterruptedException e) {
            return CompletableFuture.failedFuture(e);
        }
    }
}

// 3. 使用异步服务
@RestController
public class EmailController {
    
    @Autowired
    private EmailService emailService;
    
    @PostMapping("/send-email")
    public ResponseEntity<String> sendEmail(@RequestBody EmailRequest request) {
        CompletableFuture<String> future = emailService.sendEmail(
            request.getTo(), 
            request.getSubject(), 
            request.getBody()
        );
        
        // 非阻塞式返回
        return ResponseEntity.accepted()
            .body("邮件发送请求已接受,处理中...");
    }
}

第九部分:实战项目示例

9.1 项目概述

项目名称:在线书店系统

功能模块

  1. 用户管理(注册、登录、个人信息)
  2. 图书管理(CRUD操作)
  3. 购物车管理
  4. 订单管理
  5. 支付集成(模拟)

9.2 项目架构设计

技术栈

  • 后端:Spring Boot + Spring Data JPA + Spring Security
  • 数据库:MySQL
  • 缓存:Redis
  • 消息队列:RabbitMQ(用于异步处理订单)
  • 前端:Vue.js(可选)

9.3 核心代码实现

示例代码:购物车服务

// 1. 购物车实体
@Entity
public class CartItem {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
    
    @ManyToOne
    @JoinColumn(name = "book_id")
    private Book book;
    
    private int quantity;
    private LocalDateTime addedAt;
    
    // getters and setters
}

// 2. 购物车服务
@Service
@Transactional
public class CartService {
    
    private final CartItemRepository cartItemRepository;
    private final BookRepository bookRepository;
    private final RedisTemplate<String, Object> redisTemplate;
    
    public CartService(CartItemRepository cartItemRepository, 
                      BookRepository bookRepository,
                      RedisTemplate<String, Object> redisTemplate) {
        this.cartItemRepository = cartItemRepository;
        this.bookRepository = bookRepository;
        this.redisTemplate = redisTemplate;
    }
    
    // 添加商品到购物车(使用Redis缓存)
    public CartItem addToCart(Long userId, Long bookId, int quantity) {
        // 检查库存
        Book book = bookRepository.findById(bookId)
            .orElseThrow(() -> new RuntimeException("图书不存在"));
        
        if (book.getStock() < quantity) {
            throw new RuntimeException("库存不足");
        }
        
        // 检查是否已存在
        CartItem existingItem = cartItemRepository
            .findByUserIdAndBookId(userId, bookId);
        
        if (existingItem != null) {
            existingItem.setQuantity(existingItem.getQuantity() + quantity);
            return cartItemRepository.save(existingItem);
        }
        
        // 创建新购物车项
        CartItem cartItem = new CartItem();
        cartItem.setUser(new User(userId));
        cartItem.setBook(book);
        cartItem.setQuantity(quantity);
        cartItem.setAddedAt(LocalDateTime.now());
        
        // 保存到数据库
        CartItem savedItem = cartItemRepository.save(cartItem);
        
        // 更新Redis缓存
        String cacheKey = "cart:" + userId;
        redisTemplate.opsForList().rightPush(cacheKey, savedItem);
        
        return savedItem;
    }
    
    // 获取购物车(优先从Redis获取)
    public List<CartItem> getCart(Long userId) {
        String cacheKey = "cart:" + userId;
        
        // 尝试从Redis获取
        List<Object> cachedItems = redisTemplate.opsForList().range(cacheKey, 0, -1);
        
        if (cachedItems != null && !cachedItems.isEmpty()) {
            return cachedItems.stream()
                .map(obj -> (CartItem) obj)
                .collect(Collectors.toList());
        }
        
        // 从数据库获取并缓存
        List<CartItem> cartItems = cartItemRepository.findByUserId(userId);
        if (!cartItems.isEmpty()) {
            cartItems.forEach(item -> 
                redisTemplate.opsForList().rightPush(cacheKey, item)
            );
        }
        
        return cartItems;
    }
    
    // 清空购物车
    public void clearCart(Long userId) {
        cartItemRepository.deleteByUserId(userId);
        String cacheKey = "cart:" + userId;
        redisTemplate.delete(cacheKey);
    }
}

// 3. 订单服务(使用消息队列异步处理)
@Service
@Transactional
public class OrderService {
    
    private final OrderRepository orderRepository;
    private final CartService cartService;
    private final RabbitTemplate rabbitTemplate;
    
    public OrderService(OrderRepository orderRepository, 
                       CartService cartService,
                       RabbitTemplate rabbitTemplate) {
        this.orderRepository = orderRepository;
        this.cartService = cartService;
        this.rabbitTemplate = rabbitTemplate;
    }
    
    public Order createOrder(Long userId) {
        // 1. 获取购物车
        List<CartItem> cartItems = cartService.getCart(userId);
        
        if (cartItems.isEmpty()) {
            throw new RuntimeException("购物车为空");
        }
        
        // 2. 计算总价
        BigDecimal totalAmount = cartItems.stream()
            .map(item -> item.getBook().getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        // 3. 创建订单
        Order order = new Order();
        order.setUserId(userId);
        order.setTotalAmount(totalAmount);
        order.setStatus(OrderStatus.PENDING);
        order.setOrderTime(LocalDateTime.now());
        
        // 4. 保存订单
        Order savedOrder = orderRepository.save(order);
        
        // 5. 发送消息到消息队列(异步处理)
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setOrderId(savedOrder.getId());
        orderMessage.setUserId(userId);
        orderMessage.setTotalAmount(totalAmount);
        
        rabbitTemplate.convertAndSend("order.exchange", "order.created", orderMessage);
        
        // 6. 清空购物车
        cartService.clearCart(userId);
        
        return savedOrder;
    }
}

// 4. 消息消费者
@Component
public class OrderMessageConsumer {
    
    @RabbitListener(queues = "order.queue")
    public void processOrder(OrderMessage message) {
        System.out.println("处理订单: " + message.getOrderId());
        
        // 模拟订单处理逻辑
        try {
            Thread.sleep(3000); // 模拟耗时操作
            
            // 更新订单状态
            // orderRepository.updateStatus(message.getOrderId(), OrderStatus.PROCESSING);
            
            System.out.println("订单处理完成: " + message.getOrderId());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

第十部分:学习路径建议

10.1 阶段性学习计划

第一阶段(1-2周)

  • Java基础复习
  • Spring核心概念学习(IoC、DI、AOP)
  • Spring Boot基础使用

第二阶段(2-3周)

  • Spring Web开发(MVC、RESTful API)
  • Spring Data JPA基础
  • Spring Security基础

第三阶段(2-3周)

  • Spring Boot高级特性
  • 数据库优化与事务管理
  • 缓存与消息队列

第四阶段(3-4周)

  • 微服务架构(Spring Cloud)
  • 容器化部署(Docker)
  • 项目实战

10.2 推荐学习资源

官方文档

书籍推荐

  • 《Spring in Action》(Craig Walls著)
  • 《Spring Boot实战》(丁雪丰译)
  • 《Spring Cloud微服务实战》(翟永超著)

在线课程

  • Spring官方教程
  • Udemy上的Spring Boot课程
  • Coursera上的Spring框架课程

社区与论坛

  • Stack Overflow
  • Spring官方论坛
  • GitHub Spring项目

10.3 实践建议

  1. 从简单项目开始:先实现一个简单的CRUD应用
  2. 逐步增加复杂度:添加安全、缓存、消息队列等
  3. 阅读源码:理解Spring框架的内部实现
  4. 参与开源项目:为Spring相关项目贡献代码
  5. 持续学习:关注Spring新版本和新特性

结语

Spring框架的学习是一个循序渐进的过程,需要理论与实践相结合。通过本文提供的完整学习路径,您可以从零基础开始,逐步掌握Spring框架的核心概念和高级特性。记住,最好的学习方式是动手实践,建议您在学习每个知识点时都编写相应的示例代码,并尝试构建自己的项目。

随着技术的不断发展,Spring生态也在持续演进。保持学习的热情,关注技术社区的动态,您将能够在Java企业级开发领域不断成长和进步。祝您学习顺利!