Spring Boot通过配置类注入抽象类实现,避免空子类
解决Spring Boot中AuditService泛型Bean注入问题
问题根源
AuditBaseService<E>是抽象类,Spring无法直接实例化抽象类作为Bean- 你需要的是**
AuditService<Person>类型的具体Bean**,但原代码中没有被Spring管理的该类型实现类
配置类创建Bean的解决方案
创建一个配置类,通过@Bean方法直接生成AuditService<Person>的实例,无需编写冗余的子类:
1. 编写配置类
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AuditConfig { // 创建针对Person类型的AuditService Bean @Bean public AuditService<Person> personAuditService() { // 用匿名内部类继承抽象的AuditBaseService,生成具体实现 return new AuditBaseService<Person>() {}; } }
2. 确保Controller支持构造注入
给PersonController添加@RequiredArgsConstructor注解,让Spring通过构造方法注入Bean:
import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor public class PersonController { private final AuditService<Person> auditService; @GetMapping("/{id}/revisions") public void getHistory(@PathVariable String id) { log.info("Get Audit history for entry with id: {}", id); List<AuditEntry<Person>> auditEntryList = auditService.getEntityRevisions(id); log.debug("Profile Audit history for id: {} is : {}", id, auditEntryList); } }
关键说明
@Configuration:标记该类是Spring的配置类,Spring启动时会扫描并执行其中的@Bean方法@Bean:标记方法返回的对象会被注册到Spring容器中,成为可被注入的Bean- 匿名内部类:因为
AuditBaseService是抽象类,无法直接new,所以用匿名内部类继承它,生成一个无额外逻辑的具体实现,完全复用父类的功能 - 泛型匹配:Spring会根据
AuditService<Person>的泛型类型,自动匹配配置类中对应的Bean进行注入
扩展:多实体类的情况
如果还有其他实体(如User、Order)需要对应的AuditService,只需在配置类中添加对应的@Bean方法即可:
@Bean public AuditService<User> userAuditService() { return new AuditBaseService<User>() {}; } @Bean public AuditService<Order> orderAuditService() { return new AuditBaseService<Order>() {}; }
然后在对应的Controller中直接注入private final AuditService<User> auditService;即可,Spring会自动匹配对应的Bean。
内容的提问来源于stack exchange,提问作者Maryam Koulaei
相关产品推荐
相关产品推荐

