引言

Spring框架是Java企业级开发中最流行、最强大的框架之一。自2003年首次发布以来,Spring已经发展成为一个庞大的生态系统,涵盖了从依赖注入到微服务架构的各个方面。本文将从基础概念开始,逐步深入到高级特性和实战技巧,帮助你系统地掌握Spring框架。

第一部分:Spring基础概念

1.1 Spring框架概述

Spring是一个开源的Java开发框架,其核心设计目标是简化企业级应用的开发。Spring的主要特性包括:

  • 控制反转(IoC):将对象的创建和管理交给Spring容器
  • 依赖注入(DI):自动将依赖关系注入到对象中
  • 面向切面编程(AOP):实现横切关注点的分离
  • 声明式事务管理:简化事务处理
  • 集成支持:与各种持久化技术、Web框架等无缝集成

1.2 Spring核心模块

Spring框架由多个模块组成,每个模块都有特定的功能:

// Spring核心模块示例
// 1. Spring Core - 提供IoC容器和DI支持
// 2. Spring Context - 提供应用上下文
// 3. Spring AOP - 面向切面编程
// 4. Spring JDBC - 简化JDBC操作
// 5. Spring ORM - 集成ORM框架
// 6. Spring Web - Web应用支持
// 7. Spring MVC - Web MVC框架

1.3 Spring Boot简介

Spring Boot是Spring框架的扩展,旨在简化Spring应用的初始搭建和开发过程:

// Spring Boot应用示例
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

第二部分:依赖注入与IoC容器

2.1 IoC容器基础

Spring IoC容器负责管理应用中的对象(称为Bean)及其生命周期。

2.1.1 Bean定义方式

XML配置方式:

<!-- beans.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 构造器注入 -->
    <bean id="userService" class="com.example.service.UserService">
        <constructor-arg ref="userRepository"/>
    </bean>

    <!-- Setter注入 -->
    <bean id="userRepository" class="com.example.repository.UserRepository">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 工厂方法创建Bean -->
    <bean id="connectionFactory" class="com.example.ConnectionFactory" 
          factory-method="getInstance"/>
</beans>

注解方式:

// 使用@Component注解
@Component
public class UserService {
    private final UserRepository userRepository;
    
    // 构造器注入(推荐)
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    // 方法注入
    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

// 使用@Service、@Repository、@Controller等特定注解
@Service
public class UserServiceImpl implements UserService {
    // ...
}

@Repository
public class UserRepositoryImpl implements UserRepository {
    // ...
}

Java配置方式:

@Configuration
public class AppConfig {
    
    @Bean
    public UserService userService() {
        return new UserService(userRepository());
    }
    
    @Bean
    public UserRepository userRepository() {
        return new UserRepositoryImpl();
    }
    
    // 条件化Bean创建
    @Bean
    @ConditionalOnMissingBean
    public DataSource dataSource() {
        return new HikariDataSource();
    }
}

2.2 依赖注入的三种方式

2.2.1 构造器注入(推荐)

@Service
public class OrderService {
    private final PaymentService paymentService;
    private final NotificationService notificationService;
    
    // 构造器注入 - 依赖不可变,且明确依赖关系
    @Autowired
    public OrderService(PaymentService paymentService, 
                       NotificationService notificationService) {
        this.paymentService = paymentService;
        this.notificationService = notificationService;
    }
    
    public void processOrder(Order order) {
        paymentService.processPayment(order);
        notificationService.sendOrderConfirmation(order);
    }
}

2.2.2 Setter注入

@Service
public class OrderService {
    private PaymentService paymentService;
    private NotificationService notificationService;
    
    // Setter注入 - 适合可选依赖
    @Autowired
    public void setPaymentService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }
    
    @Autowired
    public void setNotificationService(NotificationService notificationService) {
        this.notificationService = notificationService;
    }
}

2.2.3 字段注入(不推荐)

@Service
public class OrderService {
    @Autowired
    private PaymentService paymentService;
    
    @Autowired
    private NotificationService notificationService;
    
    // 字段注入的问题:
    // 1. 难以测试(需要反射或Spring容器)
    // 2. 依赖关系不明确
    // 3. 可能导致循环依赖
}

2.3 Bean的作用域

Spring支持多种Bean作用域:

@Component
@Scope("singleton") // 单例(默认)
public class SingletonBean {
    // 整个Spring容器中只有一个实例
}

@Component
@Scope("prototype") // 原型
public class PrototypeBean {
    // 每次请求都会创建新实例
}

@Component
@Scope("request") // 请求作用域(Web环境)
public class RequestScopedBean {
    // 每个HTTP请求一个实例
}

@Component
@Scope("session") // 会话作用域(Web环境)
public class SessionScopedBean {
    // 每个HTTP会话一个实例
}

@Component
@Scope("application") // 应用作用域(Web环境)
public class ApplicationScopedBean {
    // 整个Web应用一个实例
}

2.4 Bean生命周期管理

@Component
public class LifecycleBean implements InitializingBean, DisposableBean {
    
    // 构造器
    public LifecycleBean() {
        System.out.println("1. 构造器调用");
    }
    
    // @PostConstruct注解
    @PostConstruct
    public void postConstruct() {
        System.out.println("2. @PostConstruct调用");
    }
    
    // InitializingBean接口方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("3. afterPropertiesSet调用");
    }
    
    // 自定义初始化方法
    @Bean(initMethod = "customInit")
    public void customInit() {
        System.out.println("4. 自定义初始化方法");
    }
    
    // @PreDestroy注解
    @PreDestroy
    public void preDestroy() {
        System.out.println("5. @PreDestroy调用");
    }
    
    // DisposableBean接口方法
    @Override
    public void destroy() throws Exception {
        System.out.println("6. destroy调用");
    }
    
    // 自定义销毁方法
    @Bean(destroyMethod = "customDestroy")
    public void customDestroy() {
        System.out.println("7. 自定义销毁方法");
    }
}

第三部分:Spring AOP(面向切面编程)

3.1 AOP核心概念

  • 切面(Aspect):横切关注点的模块化
  • 连接点(Join Point):程序执行过程中的某个点
  • 通知(Advice):在连接点执行的具体操作
  • 切入点(Pointcut):匹配连接点的表达式
  • 目标对象(Target):被代理的对象

3.2 AOP实现方式

3.2.1 基于注解的AOP

// 1. 定义切面
@Aspect
@Component
public class LoggingAspect {
    
    // 切入点表达式:匹配所有Service层的方法
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceMethods() {}
    
    // 前置通知
    @Before("serviceMethods()")
    public void logBefore(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("执行方法: " + methodName + " 前");
    }
    
    // 后置通知
    @After("serviceMethods()")
    public void logAfter(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("执行方法: " + methodName + " 后");
    }
    
    // 返回通知
    @AfterReturning(pointcut = "serviceMethods()", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("方法: " + methodName + " 返回: " + result);
    }
    
    // 异常通知
    @AfterThrowing(pointcut = "serviceMethods()", throwing = "ex")
    public void logAfterThrowing(JoinPoint joinPoint, Exception ex) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("方法: " + methodName + " 抛出异常: " + ex.getMessage());
    }
    
    // 环绕通知
    @Around("serviceMethods()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("方法: " + methodName + " 开始执行");
        
        try {
            Object result = joinPoint.proceed(); // 执行目标方法
            System.out.println("方法: " + methodName + " 执行成功");
            return result;
        } catch (Exception e) {
            System.out.println("方法: " + methodName + " 执行失败: " + e.getMessage());
            throw e;
        }
    }
}

3.2.2 基于XML的AOP配置

<!-- aop-config.xml -->
<aop:config>
    <!-- 定义切面 -->
    <aop:aspect ref="loggingAspect">
        <!-- 定义切入点 -->
        <aop:pointcut id="serviceMethods" 
                      expression="execution(* com.example.service.*.*(..))"/>
        
        <!-- 前置通知 -->
        <aop:before pointcut-ref="serviceMethods" 
                    method="logBefore"/>
        
        <!-- 后置通知 -->
        <aop:after pointcut-ref="serviceMethods" 
                   method="logAfter"/>
    </aop:aspect>
</aop:config>

<bean id="loggingAspect" class="com.example.aspect.LoggingAspect"/>

3.3 AOP实战:事务管理

// 使用Spring的声明式事务管理
@Service
public class OrderService {
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private PaymentService paymentService;
    
    // @Transactional注解配置事务
    @Transactional(
        propagation = Propagation.REQUIRED, // 事务传播行为
        isolation = Isolation.READ_COMMITTED, // 隔离级别
        timeout = 30, // 超时时间
        rollbackFor = {Exception.class}, // 回滚异常
        noRollbackFor = {NullPointerException.class} // 不回滚异常
    )
    public void processOrder(Order order) {
        // 1. 保存订单
        orderRepository.save(order);
        
        // 2. 处理支付
        paymentService.processPayment(order);
        
        // 3. 发送通知
        sendNotification(order);
    }
    
    // 事务传播行为示例
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void processPaymentInNewTransaction(Order order) {
        // 这个方法会在新的事务中执行
        paymentService.processPayment(order);
    }
    
    // 只读事务
    @Transactional(readOnly = true)
    public List<Order> findOrdersByUser(Long userId) {
        return orderRepository.findByUserId(userId);
    }
}

第四部分:Spring MVC

4.1 Spring MVC架构

Spring MVC遵循经典的MVC模式:

  • Model:数据模型
  • View:视图(JSP、Thymeleaf等)
  • Controller:控制器

4.2 创建Controller

// 1. 基础Controller
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    // GET请求 - 获取用户列表
    @GetMapping
    public ResponseEntity<List<User>> getAllUsers() {
        List<User> users = userService.findAll();
        return ResponseEntity.ok(users);
    }
    
    // GET请求 - 获取单个用户
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.findById(id);
        return ResponseEntity.ok(user);
    }
    
    // POST请求 - 创建用户
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User createdUser = userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
    }
    
    // PUT请求 - 更新用户
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Long id, 
                                          @RequestBody User user) {
        user.setId(id);
        User updatedUser = userService.update(user);
        return ResponseEntity.ok(updatedUser);
    }
    
    // DELETE请求 - 删除用户
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.delete(id);
        return ResponseEntity.noContent().build();
    }
}

4.3 请求参数处理

@RestController
@RequestMapping("/api/orders")
public class OrderController {
    
    // 路径参数
    @GetMapping("/{id}")
    public Order getOrderById(@PathVariable Long id) {
        return orderService.findById(id);
    }
    
    // 查询参数
    @GetMapping("/search")
    public List<Order> searchOrders(@RequestParam String status, 
                                   @RequestParam(defaultValue = "10") int limit) {
        return orderService.findByStatus(status, limit);
    }
    
    // 请求体参数
    @PostMapping
    public Order createOrder(@RequestBody Order order) {
        return orderService.create(order);
    }
    
    // 表单参数
    @PostMapping("/form")
    public Order createOrderFromForm(@RequestParam String customerName,
                                    @RequestParam String productCode) {
        Order order = new Order();
        order.setCustomerName(customerName);
        order.setProductCode(productCode);
        return orderService.create(order);
    }
    
    // 复杂对象参数
    @PostMapping("/complex")
    public Order createComplexOrder(@RequestBody OrderRequest request) {
        // OrderRequest包含多个字段和嵌套对象
        return orderService.create(request.toOrder());
    }
    
    // 文件上传
    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return ResponseEntity.badRequest().body("文件不能为空");
        }
        
        try {
            // 处理文件
            String fileName = file.getOriginalFilename();
            // 保存文件逻辑...
            return ResponseEntity.ok("文件上传成功: " + fileName);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                               .body("文件上传失败: " + e.getMessage());
        }
    }
}

4.4 数据验证

// 1. 定义验证注解
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EmailValidator.class)
public @interface ValidEmail {
    String message() default "无效的邮箱格式";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

// 2. 实现验证器
public class EmailValidator implements ConstraintValidator<ValidEmail, String> {
    @Override
    public boolean isValid(String email, ConstraintValidatorContext context) {
        if (email == null) return true;
        return email.matches("^[A-Za-z0-9+_.-]+@(.+)$");
    }
}

// 3. 在实体类中使用
public class User {
    @NotBlank(message = "用户名不能为空")
    @Size(min = 3, max = 20, message = "用户名长度必须在3-20之间")
    private String username;
    
    @ValidEmail
    private String email;
    
    @Min(value = 18, message = "年龄必须大于等于18岁")
    @Max(value = 100, message = "年龄不能超过100岁")
    private Integer age;
    
    // getters and setters
}

// 4. 在Controller中使用
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @PostMapping
    public ResponseEntity<User> createUser(@Valid @RequestBody User user, 
                                          BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            // 收集所有错误信息
            List<String> errors = bindingResult.getAllErrors()
                .stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.toList());
            
            return ResponseEntity.badRequest().body(null);
        }
        
        User savedUser = userService.save(user);
        return ResponseEntity.ok(savedUser);
    }
}

第五部分:Spring Data JPA

5.1 JPA基础

// 1. 实体类定义
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "username", nullable = false, length = 50)
    private String username;
    
    @Column(name = "email", unique = true)
    private String email;
    
    @Column(name = "age")
    private Integer age;
    
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Order> orders = new ArrayList<>();
    
    // 构造函数、getter、setter
}

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

5.2 事务管理

@Service
@Transactional
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private OrderRepository orderRepository;
    
    // 事务传播行为示例
    @Transactional(propagation = Propagation.REQUIRED)
    public User createUserWithOrders(User user, List<Order> orders) {
        // 保存用户
        user = userRepository.save(user);
        
        // 设置订单关联
        orders.forEach(order -> order.setUser(user));
        
        // 保存订单
        orderRepository.saveAll(orders);
        
        return user;
    }
    
    // 事务回滚示例
    @Transactional(rollbackFor = Exception.class)
    public void processUserWithRollback(User user) {
        userRepository.save(user);
        
        // 模拟异常
        if (user.getAge() < 18) {
            throw new RuntimeException("年龄不能小于18岁");
        }
        
        // 这行代码不会执行,因为上面抛出了异常
        System.out.println("用户处理完成");
    }
    
    // 只读事务
    @Transactional(readOnly = true)
    public List<User> findAllUsers() {
        return userRepository.findAll();
    }
}

第六部分:Spring Security

6.1 基础配置

// 1. 安全配置类
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable() // 禁用CSRF(对于REST API)
            .authorizeHttpRequests(authz -> authz
                // 允许匿名访问的端点
                .requestMatchers("/api/public/**").permitAll()
                // 需要认证的端点
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .requestMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
                // 其他所有请求都需要认证
                .anyRequest().authenticated()
            )
            // 表单登录配置
            .formLogin(form -> form
                .loginPage("/login")
                .defaultSuccessUrl("/dashboard")
                .permitAll()
            )
            // HTTP Basic认证
            .httpBasic(basic -> basic
                .realmName("MyApp")
            )
            // 登出配置
            .logout(logout -> logout
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout")
                .permitAll()
            );
        
        return http.build();
    }
    
    // 密码编码器
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    // 用户详情服务
    @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("admin123"))
            .roles("ADMIN", "USER")
            .build();
        
        return new InMemoryUserDetailsManager(user, admin);
    }
}

6.2 基于数据库的认证

// 1. 实体类
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(unique = true, nullable = false)
    private String username;
    
    @Column(nullable = false)
    private String password;
    
    @Column(nullable = false)
    private String email;
    
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
        name = "user_roles",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id")
    )
    private Set<Role> roles = new HashSet<>();
    
    // getters and setters
}

@Entity
@Table(name = "roles")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(unique = true, nullable = false)
    private String name; // ROLE_USER, ROLE_ADMIN
    
    @ManyToMany(mappedBy = "roles")
    private Set<User> users = new HashSet<>();
    
    // getters and setters
}

// 2. Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByUsername(String username);
}

// 3. 自定义UserDetailsService
@Service
public class CustomUserDetailsService implements UserDetailsService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + username));
        
        return org.springframework.security.core.userdetails.User
            .withUsername(user.getUsername())
            .password(user.getPassword())
            .authorities(user.getRoles().stream()
                .map(role -> new SimpleGrantedAuthority(role.getName()))
                .collect(Collectors.toList()))
            .build();
    }
}

// 4. 更新安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Autowired
    private CustomUserDetailsService userDetailsService;
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/api/public/**").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginPage("/login")
                .defaultSuccessUrl("/dashboard")
                .permitAll()
            )
            .logout(logout -> logout
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout")
                .permitAll()
            );
        
        return http.build();
    }
    
    @Bean
    public AuthenticationManager authenticationManager(
            AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

第七部分:Spring Boot实战

7.1 Spring Boot项目结构

my-spring-boot-app/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           └── myapp/
│   │   │               ├── Application.java          # 主启动类
│   │   │               ├── config/                   # 配置类
│   │   │               ├── controller/               # 控制器
│   │   │               ├── service/                  # 服务层
│   │   │               ├── repository/               # 数据访问层
│   │   │               ├── entity/                   # 实体类
│   │   │               ├── dto/                      # 数据传输对象
│   │   │               └── exception/                # 异常处理
│   │   └── resources/
│   │       ├── application.yml                      # 主配置文件
│   │       ├── application-dev.yml                  # 开发环境配置
│   │       ├── application-prod.yml                 # 生产环境配置
│   │       └── static/                              # 静态资源
│   └── test/
│       └── java/
│           └── com/
│               └── example/
│                   └── myapp/
│                       └── test/                    # 测试类
└── pom.xml                                          # Maven配置

7.2 配置管理

# application.yml
server:
  port: 8080
  servlet:
    context-path: /api

spring:
  # 数据源配置
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      maximum-pool-size: 20
      connection-timeout: 30000
  
  # JPA配置
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        format_sql: true
        dialect: org.hibernate.dialect.MySQL8Dialect
  
  # 邮件配置
  mail:
    host: smtp.gmail.com
    port: 587
    username: your-email@gmail.com
    password: your-password
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true
  
  # 缓存配置
  cache:
    type: redis
    redis:
      time-to-live: 3600000
  
  # 消息队列配置
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

# 自定义配置
app:
  name: My Spring Boot Application
  version: 1.0.0
  features:
    email-notifications: true
    sms-notifications: false
  admin-emails:
    - admin1@example.com
    - admin2@example.com

7.3 配置类示例

@Configuration
@ConfigurationProperties(prefix = "app")
public class AppConfig {
    
    private String name;
    private String version;
    private Features features;
    private List<String> adminEmails = new ArrayList<>();
    
    // Getters and Setters
    
    public static class Features {
        private boolean emailNotifications;
        private boolean smsNotifications;
        
        // Getters and Setters
    }
    
    @Bean
    public EmailService emailService() {
        return new EmailService(features.emailNotifications);
    }
}

7.4 Spring Boot Starter

// 1. 创建自定义Starter
// pom.xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

// 2. 配置类
@Configuration
@ConditionalOnClass({DataSource.class, JdbcTemplate.class})
@ConditionalOnMissingBean(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class CustomDataSourceAutoConfiguration {
    
    @Bean
    @ConfigurationProperties(prefix = "custom.datasource")
    public DataSource dataSource(DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }
}

// 3. 配置属性类
@ConfigurationProperties(prefix = "custom.datasource")
public class DataSourceProperties {
    private String url;
    private String username;
    private String password;
    private String driverClassName;
    
    // Getters and Setters
}

第八部分:Spring高级特性

8.1 事件驱动编程

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

// 2. 事件发布者
@Service
public class UserService {
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    public void registerUser(User user) {
        // 保存用户
        userRepository.save(user);
        
        // 发布事件
        eventPublisher.publishEvent(new UserRegisteredEvent(this, user));
    }
}

// 3. 事件监听器
@Component
public class UserEventListener {
    
    @EventListener
    public void handleUserRegistered(UserRegisteredEvent event) {
        User user = event.getUser();
        System.out.println("用户注册事件处理: " + user.getUsername());
        
        // 发送欢迎邮件
        emailService.sendWelcomeEmail(user.getEmail());
        
        // 记录日志
        logService.logUserRegistration(user.getId());
    }
    
    @EventListener
    @Async // 异步处理
    public void handleUserRegisteredAsync(UserRegisteredEvent event) {
        // 异步处理,不阻塞主线程
        System.out.println("异步处理用户注册事件");
    }
}

8.2 异步处理

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

// 2. 异步方法
@Service
public class EmailService {
    
    @Async
    public CompletableFuture<String> sendEmail(String to, String subject, String content) {
        try {
            // 模拟发送邮件
            Thread.sleep(2000);
            System.out.println("发送邮件到: " + to);
            return CompletableFuture.completedFuture("邮件发送成功");
        } catch (InterruptedException e) {
            return CompletableFuture.failedFuture(e);
        }
    }
    
    @Async
    public void sendBulkEmails(List<String> recipients) {
        recipients.forEach(recipient -> {
            sendEmail(recipient, "通知", "您的订单已处理");
        });
    }
}

// 3. 异步调用
@Service
public class OrderService {
    
    @Autowired
    private EmailService emailService;
    
    public void processOrder(Order order) {
        // 同步处理订单
        orderRepository.save(order);
        
        // 异步发送邮件
        CompletableFuture<String> emailFuture = emailService.sendEmail(
            order.getCustomerEmail(),
            "订单确认",
            "您的订单已确认"
        );
        
        // 可以继续其他操作,不等待邮件发送完成
        System.out.println("订单处理完成,邮件发送中...");
        
        // 如果需要等待结果
        emailFuture.thenAccept(result -> {
            System.out.println("邮件发送结果: " + result);
        });
    }
}

8.3 缓存管理

// 1. 启用缓存
@Configuration
@EnableCaching
public class CacheConfig {
    
    @Bean
    public CacheManager cacheManager() {
        // 使用Redis作为缓存
        RedisCacheManager redisCacheManager = RedisCacheManager.builder(
            RedisConnectionFactory.create())
            .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10))
                .disableCachingNullValues())
            .build();
        return redisCacheManager;
    }
}

// 2. 使用缓存注解
@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    // 缓存查询结果
    @Cacheable(value = "users", key = "#id")
    public User getUserById(Long id) {
        System.out.println("从数据库查询用户: " + id);
        return userRepository.findById(id).orElse(null);
    }
    
    // 更新缓存
    @CachePut(value = "users", key = "#user.id")
    public User updateUser(User user) {
        System.out.println("更新用户: " + user.getId());
        return userRepository.save(user);
    }
    
    // 删除缓存
    @CacheEvict(value = "users", key = "#id")
    public void deleteUser(Long id) {
        System.out.println("删除用户: " + id);
        userRepository.deleteById(id);
    }
    
    // 条件缓存
    @Cacheable(value = "users", key = "#id", unless = "#result == null")
    public User getUserByIdConditional(Long id) {
        return userRepository.findById(id).orElse(null);
    }
}

第九部分:Spring测试

9.1 单元测试

// 1. 使用JUnit 5和Mockito
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    
    @Mock
    private UserRepository userRepository;
    
    @Mock
    private EmailService emailService;
    
    @InjectMocks
    private UserService userService;
    
    @Test
    void shouldCreateUser() {
        // 准备测试数据
        User user = new User();
        user.setUsername("testuser");
        user.setEmail("test@example.com");
        
        // 模拟行为
        when(userRepository.save(any(User.class))).thenReturn(user);
        doNothing().when(emailService).sendWelcomeEmail(anyString());
        
        // 执行测试
        User result = userService.createUser(user);
        
        // 验证结果
        assertNotNull(result);
        assertEquals("testuser", result.getUsername());
        
        // 验证方法调用
        verify(userRepository, times(1)).save(user);
        verify(emailService, times(1)).sendWelcomeEmail("test@example.com");
    }
    
    @Test
    void shouldThrowExceptionWhenUserExists() {
        // 准备测试数据
        User user = new User();
        user.setUsername("existinguser");
        
        // 模拟行为
        when(userRepository.findByUsername("existinguser"))
            .thenReturn(Optional.of(user));
        
        // 执行测试并验证异常
        assertThrows(UserAlreadyExistsException.class, () -> {
            userService.createUser(user);
        });
    }
}

9.2 集成测试

// 1. Spring Boot集成测试
@SpringBootTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Transactional // 测试完成后回滚
class UserServiceIntegrationTest {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private UserRepository userRepository;
    
    @Test
    void shouldCreateUserAndSaveToDatabase() {
        // 准备测试数据
        User user = new User();
        user.setUsername("integrationtest");
        user.setEmail("integration@test.com");
        
        // 执行测试
        User savedUser = userService.createUser(user);
        
        // 验证结果
        assertNotNull(savedUser.getId());
        
        // 验证数据库
        User foundUser = userRepository.findById(savedUser.getId()).orElse(null);
        assertNotNull(foundUser);
        assertEquals("integrationtest", foundUser.getUsername());
    }
}

// 2. Web层集成测试
@WebMvcTest(UserController.class)
class UserControllerWebTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @MockBean
    private UserService userService;
    
    @Test
    void shouldGetUserById() throws Exception {
        // 准备测试数据
        User user = new User();
        user.setId(1L);
        user.setUsername("testuser");
        
        // 模拟行为
        when(userService.getUserById(1L)).thenReturn(user);
        
        // 执行测试
        mockMvc.perform(get("/api/users/1"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.id").value(1))
            .andExpect(jsonPath("$.username").value("testuser"));
    }
}

第十部分:Spring Cloud微服务

10.1 Spring Cloud基础

// 1. 服务注册与发现(Eureka)
// 服务提供者
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

// application.yml
spring:
  application:
    name: user-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

// 2. 服务消费者
@RestController
public class OrderController {
    
    @Autowired
    private RestTemplate restTemplate;
    
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    @GetMapping("/orders/{id}")
    public Order getOrderWithUser(@PathVariable Long id) {
        // 通过服务名调用,而不是直接调用IP
        User user = restTemplate.getForObject(
            "http://user-service/api/users/{userId}", 
            User.class, 
            order.getUserId()
        );
        
        Order order = orderService.getOrder(id);
        order.setUser(user);
        return order;
    }
}

10.2 API网关(Spring Cloud Gateway)

// 1. 网关配置
@Configuration
public class GatewayConfig {
    
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("user-service", r -> r
                .path("/api/users/**")
                .uri("lb://user-service"))
            .route("order-service", r -> r
                .path("/api/orders/**")
                .uri("lb://order-service"))
            .route("auth-service", r -> r
                .path("/api/auth/**")
                .uri("lb://auth-service"))
            .build();
    }
}

// 2. 自定义过滤器
@Component
public class LoggingFilter implements GlobalFilter, Ordered {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 请求前处理
        System.out.println("请求路径: " + exchange.getRequest().getPath());
        System.out.println("请求方法: " + exchange.getRequest().getMethod());
        
        // 继续执行过滤器链
        return chain.filter(exchange)
            .doOnSuccess(v -> {
                // 响应后处理
                System.out.println("响应状态: " + exchange.getResponse().getStatusCode());
            });
    }
    
    @Override
    public int getOrder() {
        return -1; // 优先级
    }
}

10.3 配置中心(Spring Cloud Config)

// 1. 配置服务器
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}

// application.yml
server:
  port: 8888

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/your-repo/config-repo
          search-paths: config
          username: your-username
          password: your-password
          default-label: main

// 2. 配置客户端
@SpringBootApplication
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

// bootstrap.yml
spring:
  application:
    name: user-service
  cloud:
    config:
      uri: http://localhost:8888
      profile: dev
      label: main

第十一部分:性能优化与最佳实践

11.1 性能优化技巧

// 1. 数据库连接池优化
@Configuration
public class DataSourceConfig {
    
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public HikariDataSource dataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        
        // 优化配置
        dataSource.setMaximumPoolSize(20); // 根据并发量调整
        dataSource.setMinimumIdle(5);
        dataSource.setConnectionTimeout(30000);
        dataSource.setIdleTimeout(600000);
        dataSource.setMaxLifetime(1800000);
        dataSource.setLeakDetectionThreshold(60000);
        
        return dataSource;
    }
}

// 2. 查询优化
@Service
public class UserService {
    
    // 避免N+1查询问题
    @Query("SELECT u FROM User u LEFT JOIN FETCH u.orders WHERE u.id = :id")
    User getUserWithOrders(@Param("id") Long id);
    
    // 使用分页查询
    public Page<User> findUsersByAge(Integer age, int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("username"));
        return userRepository.findByAgeGreaterThan(age, pageable);
    }
    
    // 批量操作
    @Transactional
    public void batchUpdateUsers(List<User> users) {
        users.forEach(user -> {
            userRepository.save(user);
        });
    }
}

// 3. 缓存优化
@Service
public class ProductService {
    
    @Cacheable(value = "products", key = "#id", 
               unless = "#result == null", 
               sync = true) // 防止缓存击穿
    public Product getProductById(Long id) {
        return productRepository.findById(id).orElse(null);
    }
    
    @Cacheable(value = "products", key = "'category:' + #category")
    public List<Product> getProductsByCategory(String category) {
        return productRepository.findByCategory(category);
    }
}

11.2 最佳实践

// 1. 分层架构
// Controller层 - 只负责请求处理和响应
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping("/{id}")
    public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return ResponseEntity.ok(UserDTO.from(user));
    }
}

// Service层 - 业务逻辑
@Service
@Transactional
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private EmailService emailService;
    
    public User getUserById(Long id) {
        return userRepository.findById(id)
            .orElseThrow(() -> new UserNotFoundException(id));
    }
    
    public User createUser(User user) {
        // 业务验证
        if (userRepository.existsByUsername(user.getUsername())) {
            throw new UserAlreadyExistsException(user.getUsername());
        }
        
        // 保存用户
        User savedUser = userRepository.save(user);
        
        // 发送通知
        emailService.sendWelcomeEmail(savedUser.getEmail());
        
        return savedUser;
    }
}

// Repository层 - 数据访问
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    
    Optional<User> findByUsername(String username);
    
    boolean existsByUsername(String username);
    
    @Query("SELECT u FROM User u WHERE u.email = :email")
    Optional<User> findByEmail(@Param("email") String email);
}

// DTO层 - 数据传输对象
public class UserDTO {
    private Long id;
    private String username;
    private String email;
    private Integer age;
    
    // 构造函数、getter、setter
    
    public static UserDTO from(User user) {
        UserDTO dto = new UserDTO();
        dto.setId(user.getId());
        dto.setUsername(user.getUsername());
        dto.setEmail(user.getEmail());
        dto.setAge(user.getAge());
        return dto;
    }
}

// 2. 异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(UserNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ErrorResponse handleUserNotFound(UserNotFoundException ex) {
        return new ErrorResponse("USER_NOT_FOUND", ex.getMessage());
    }
    
    @ExceptionHandler(UserAlreadyExistsException.class)
    @ResponseStatus(HttpStatus.CONFLICT)
    public ErrorResponse handleUserAlreadyExists(UserAlreadyExistsException ex) {
        return new ErrorResponse("USER_ALREADY_EXISTS", ex.getMessage());
    }
    
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ErrorResponse handleValidationException(MethodArgumentNotValidException ex) {
        List<String> errors = ex.getBindingResult().getAllErrors()
            .stream()
            .map(DefaultMessageSourceResolvable::getDefaultMessage)
            .collect(Collectors.toList());
        return new ErrorResponse("VALIDATION_ERROR", String.join(", ", errors));
    }
    
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResponse handleGenericException(Exception ex) {
        return new ErrorResponse("INTERNAL_ERROR", "系统内部错误");
    }
}

// 3. 配置管理
@Configuration
public class AppConfig {
    
    @Value("${app.feature.enabled:false}")
    private boolean featureEnabled;
    
    @Bean
    @ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true")
    public FeatureService featureService() {
        return new FeatureService();
    }
    
    @Bean
    @ConditionalOnMissingBean(FeatureService.class)
    public FeatureService defaultFeatureService() {
        return new DefaultFeatureService();
    }
}

第十二部分:Spring学习路线图

12.1 初级阶段(1-2个月)

  1. Java基础:掌握Java核心语法、集合框架、多线程
  2. Spring Core:深入理解IoC、DI、Bean生命周期
  3. Spring MVC:掌握Web开发基础
  4. Spring Data JPA:学习数据库操作
  5. Spring Boot:快速搭建项目

12.2 中级阶段(3-4个月)

  1. Spring AOP:掌握面向切面编程
  2. Spring Security:学习安全认证与授权
  3. Spring事务管理:理解事务传播行为
  4. Spring测试:单元测试与集成测试
  5. 性能优化:数据库优化、缓存策略

12.3 高级阶段(5-6个月)

  1. Spring Cloud:微服务架构
  2. Spring Boot高级特性:自定义Starter、自动配置
  3. 设计模式:在Spring中应用设计模式
  4. 架构设计:DDD、Clean Architecture
  5. 监控与运维:Actuator、Micrometer

12.4 专家阶段(持续学习)

  1. 源码阅读:深入Spring源码
  2. 框架扩展:自定义Spring组件
  3. 性能调优:JVM调优、GC优化
  4. 云原生:Kubernetes、Docker集成
  5. 领域专家:特定行业解决方案

结语

Spring框架是一个庞大而强大的生态系统,掌握它需要时间和实践。本文从基础概念到高级特性,系统地介绍了Spring的核心知识点。学习Spring的关键在于:

  1. 理论与实践结合:每个概念都要通过代码实践来理解
  2. 循序渐进:不要急于求成,打好基础再进阶
  3. 阅读源码:理解Spring的内部机制
  4. 参与社区:关注Spring官方文档和社区动态
  5. 持续学习:技术不断更新,保持学习热情

记住,最好的学习方式是动手实践。建议从一个简单的项目开始,逐步添加复杂功能,最终构建一个完整的应用。祝你在Spring的学习之旅中取得成功!