前言:为什么需要自定义Bean?
在Spring Boot开发中,Bean是构成应用程序的基本单元。虽然Spring Boot提供了大量的自动配置,但在实际项目中,我们经常需要创建自定义Bean来满足特定的业务需求。本文将深入探讨Spring Boot中自定义Bean的多种实现方式,帮助开发者更好地掌握这一核心技术。
TRAE IDE智能提示:在TRAE IDE中编写Spring Boot代码时,AI助手会智能识别您的Bean定义需求,自动推荐合适的注解和配置方式,大大提升开发效率。
01|Spring Boot Bean基础概念
Bean的定义与作用
Bean是Spring框架管理的对象,它们由Spring IoC容器实例化、配置和管理。在Spring Boot中,Bean可以是任何普通的Java对象,通过特定的注解或配置方式声明为Spring管理的组件。
Bean的生命周期
Spring Bean的生命周期包括以下几个关键阶段:
- 实例化(Instantiation)
- 属性赋值(Populate Properties)
- 初始化(Initialization)
- 销毁(Destruction)
@Component
public class MyBean {
public MyBean() {
System.out.println("1. Bean实例化");
}
@PostConstruct
public void init() {
System.out.println("3. Bean初始化");
}
@PreDestroy
public void destroy() {
System.out.println("4. Bean销毁");
}
}02|使用@Configuration和@Bean注解
@Configuration注解详解
@Configuration注解用于标记一个类为配置类,相当于传统的XML配置文件。被注解的类可以包含一个或多个@Bean方法。
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
return DataSourceBuilder.create()
.url("jdbc:mysql://localhost:3306/test")
.username("root")
.password("password")
.driverClassName("com.mysql.cj.jdbc.Driver")
.build();
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}@Bean注解的高级用法
@Bean注解支持多种属性配置:
@Configuration
public class AdvancedConfig {
@Bean(name = "customRestTemplate")
@Primary
@Scope("prototype")
@Lazy
public RestTemplate customRestTemplate() {
RestTemplate template = new RestTemplate();
template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
return template;
}
@Bean
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public FeatureService featureService() {
return new FeatureService();
}
}TRAE IDE代码生成:在TRAE IDE中,您只需输入"创建RestTemplate Bean",AI助手就能自动生成完整的配置代码,包括常用的消息转换器设置。
03|组件扫描注解详解
@Component及其派生注解
Spring提供了多个组件注解,用于不同层级的组件标识:
// 通用组件
@Component
public class UtilityService {
public String processData(String input) {
return input.toUpperCase();
}
}
// 服务层组件
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User findUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
}
// 数据访问层组件
@Repository
public class UserRepository {
public Optional<User> findById(Long id) {
// 模拟数据库查询
return Optional.of(new User(id, "Test User"));
}
}
// 控制器组件
@Controller
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users/{id}")
@ResponseBody
public User getUser(@PathVariable Long id) {
return userService.findUserById(id);
}
}自定义组件注解
可以创建自定义的组件注解来满足特定需求:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface CustomComponent {
String value() default "";
String description() default "";
}
// 使用自定义注解
@CustomComponent(value = "myCustomBean", description = "自定义组件")
public class CustomService {
public void doSomething() {
System.out.println("Custom service is working!");
}
}04|依赖注入最佳实践
构造器注入(推荐)
@Service
public class OrderService {
private final OrderRepository orderRepository;
private final PaymentService paymentService;
@Autowired
public OrderService(OrderRepository orderRepository,
PaymentService paymentService) {
this.orderRepository = orderRepository;
this.paymentService = paymentService;
}
}Setter注入
@Service
public class ProductService {
private ProductRepository productRepository;
private InventoryService inventoryService;
@Autowired
public void setProductRepository(ProductRepository productRepository) {
this.productRepository = productRepository;
}
@Autowired(required = false)
public void setInventoryService(InventoryService inventoryService) {
this.inventoryService = inventoryService;
}
}字段注入(不推荐)
@Service
public class CustomerService {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private EmailService emailService;
}TRAE IDE智能检测:TRAE IDE会自动检测注入方式的合理性,推荐使用构造器注入,并提供一键重构功能,帮助您优化代码质量。
05|条件化Bean定义
@Conditional系列注解
Spring Boot提供了丰富的条件注解:
@Configuration
public class ConditionalConfig {
@Bean
@ConditionalOnClass(name = "com.fasterxml.jackson.databind.ObjectMapper")
public JacksonConverter jacksonConverter() {
return new JacksonConverter();
}
@Bean
@ConditionalOnMissingBean(DataSource.class)
public DataSource defaultDataSource() {
return DataSourceBuilder.create()
.url("jdbc:h2:mem:testdb")
.build();
}
@Bean
@ConditionalOnProperty(prefix = "app.cache", name = "enabled", havingValue = "true")
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
@Bean
@ConditionalOnExpression("${app.feature.complex:false} and ${app.feature.advanced:false}")
public ComplexFeature complexFeature() {
return new ComplexFeature();
}
}自定义条件注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(CustomCondition.class)
public @interface ConditionalOnCustom {
String value();
}
public class CustomCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String value = (String) metadata.getAnnotationAttributes(
ConditionalOnCustom.class.getName()).get("value");
return "enabled".equals(value);
}
}06|实战案例:构建完整的业务 系统
案例:电商订单处理系统
// 实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
private Long id;
private String orderNumber;
private BigDecimal amount;
private OrderStatus status;
}
// 枚举
public enum OrderStatus {
PENDING, CONFIRMED, SHIPPED, DELIVERED, CANCELLED
}
// 配置类
@Configuration
@EnableConfigurationProperties(OrderProperties.class)
public class OrderConfig {
@Bean
public OrderProcessor orderProcessor() {
return new OrderProcessor();
}
@Bean
@ConditionalOnProperty(name = "order.notification.enabled", havingValue = "true")
public OrderNotificationService notificationService() {
return new OrderNotificationService();
}
}
// 服务类
@Service
public class OrderService {
private final OrderRepository orderRepository;
private final PaymentService paymentService;
private final InventoryService inventoryService;
private final Optional<OrderNotificationService> notificationService;
@Autowired
public OrderService(OrderRepository orderRepository,
PaymentService paymentService,
InventoryService inventoryService,
Optional<OrderNotificationService> notificationService) {
this.orderRepository = orderRepository;
this.paymentService = paymentService;
this.inventoryService = inventoryService;
this.notificationService = notificationService;
}
@Transactional
public Order createOrder(Order order) {
// 检查库存
inventoryService.checkInventory(order);
// 处理支付
paymentService.processPayment(order);
// 保存订单
Order savedOrder = orderRepository.save(order);
// 发送通知(如果启用)
notificationService.ifPresent(service ->
service.sendOrderConfirmation(savedOrder));
return savedOrder;
}
}
// 仓库类
@Repository
public class OrderRepository {
private final Map<Long, Order> orders = new ConcurrentHashMap<>();
private final AtomicLong idGenerator = new AtomicLong(1);
public Order save(Order order) {
if (order.getId() == null) {
order.setId(idGenerator.getAndIncrement());
}
orders.put(order.getId(), order);
return order;
}
public Optional<Order> findById(Long id) {
return Optional.ofNullable(orders.get(id));
}
public List<Order> findAll() {
return new ArrayList<>(orders.values());
}
}配置属性类
@ConfigurationProperties(prefix = "order")
@Data
public class OrderProperties {
private int maxOrderAmount = 10000;
private Duration orderTimeout = Duration.ofMinutes(30);
private Notification notification = new Notification();
@Data
public static class Notification {
private boolean enabled = true;
private String emailTemplate = "order-confirmation";
private String smsTemplate = "order-sms";
}
}