Spring Boot 中使用 Lombok 进行依赖注入的示例
Spring Boot 中使用 Lombok 进行依赖注入的示例
下面我将展示 Spring Boot 中使用 Lombok 进行依赖注入的不同方式,包括构造器注入、属性注入和 setter 方法注入,以及相应的测试用例。
1. 构造器注入(推荐方式)
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;@Service
@RequiredArgsConstructor
public class UserService {private final UserRepository userRepository;private final PasswordEncoder passwordEncoder;// Lombok 会自动生成包含所有 final 字段的构造器// 相当于:// public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {// this.userRepository = userRepository;// this.passwordEncoder = passwordEncoder;// }
}
2. 属性注入(不推荐,仅作演示)
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class OrderService {@Autowired@Setterprivate PaymentService paymentService;@Autowired@Setterprivate InventoryService inventoryService;
}
3. Setter 方法注入
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class ProductService {private ProductRepository productRepository;private DiscountService discountService;@Autowiredpublic void setProductRepository(ProductRepository productRepository) {this.productRepository = productRepository;}@Autowired@Setter // 也可以使用 Lombok 的 @Setter 注解public void setDiscountService(DiscountService discountService) {this.discountService = discountService;}
}
4. 测试用例示例
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;@ExtendWith(MockitoExtension.class)
public class UserServiceTest {@Mockprivate UserRepository userRepository;@Mockprivate PasswordEncoder passwordEncoder;@InjectMocksprivate UserService userService;@Testpublic void testCreateUser() {// 准备测试数据String username = "testUser";String password = "password123";String encodedPassword = "encodedPassword123";// 定义 mock 行为when(passwordEncoder.encode(password)).thenReturn(encodedPassword);when(userRepository.save(any(User.class))).thenAnswer(invocation -> invocation.getArgument(0));// 执行测试User result = userService.createUser(username, password);// 验证结果assertNotNull(result);assertEquals(username, result.getUsername());assertEquals(encodedPassword, result.getPassword());// 验证交互verify(passwordEncoder).encode(password);verify(userRepository).save(any(User.class));}
}
5. 综合示例(使用 Lombok 和 Spring)
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;@Controller
@RequiredArgsConstructor
@RequestMapping("/api/users")
public class UserController {private final UserService userService;private final AuditService auditService;@PostMappingpublic ResponseEntity<User> createUser(@RequestBody UserDto userDto) {User user = userService.createUser(userDto);auditService.logUserCreation(user);return ResponseEntity.ok(user);}
}
springboot 测试代码中使用构造方法
@SpringBootTest
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class Test1RepositoryTest {protected final CcProcessRepository ccProcessRepository;
其他参考: lombok.config,lombok1.8.30 测试类未生效,只生成了 @ConstructorProperties
# 阻止配置向上冒泡
#config.stopBubbling = true
# 全局同时配置两种注解(需要Lombok 1.18.16+)
# 为所有生成的构造器自动添加 @ConstructorProperties
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Autowired
lombok.anyConstructor.addConstructorProperties = true
#lombok.copyableAnnotations += org.springframework.context.annotation.Lazy
注意事项
-
推荐使用构造器注入(使用
@RequiredArgsConstructor
),因为:- 明确依赖关系
- 方便测试
- 不可变(final)字段
- 符合单一职责原则
-
属性注入虽然简洁,但有以下缺点:
- 隐藏依赖关系
- 难以测试
- 可能导致循环依赖
-
在测试中,使用
@Mock
创建 mock 对象,使用@InjectMocks
让 Mockito 自动注入这些 mock 到被测试对象中。 -
确保项目中已正确配置 Lombok 插件(IDE 和构建工具都需要)。