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
@Setter
private PaymentService paymentService;
@Autowired
@Setter
private 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;
@Autowired
public 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 {
@Mock
private UserRepository userRepository;
@Mock
private PasswordEncoder passwordEncoder;
@InjectMocks
private UserService userService;
@Test
public 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;
@PostMapping
public 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 和构建工具都需要)。