如何为自定义Couchbase Repository注入ExtensionHelper字段?
问题原因
Spring Data的Repository实现类是由框架动态实例化的,不属于Spring容器直接管理的Bean,所以直接给SimpleCustomRepository的字段加@Autowired不会生效。下面是几种可行的注入方案:
方案一:自定义RepositoryFactoryBean传入依赖(推荐)
这是最符合Spring规范的做法,通过扩展Spring Data的工厂类来注入ExtensionHelper:
- 修改
SimpleCustomRepository,改用构造方法接收ExtensionHelper:
public class SimpleCustomRepository<T, ID> extends SimpleCouchbaseRepository<T, ID> { private final ExtensionHelper extensionHelper; // 将ExtensionHelper加入构造参数 public SimpleCustomRepository(CouchbaseEntityInformation<T, String> entityInformation, CouchbaseOperations couchbaseOperations, Class<?> repositoryInterface, ExtensionHelper extensionHelper) { super(entityInformation, couchbaseOperations, repositoryInterface); this.extensionHelper = extensionHelper; } @Override public <S extends T> S save(S entity) { extensionHelper.applyExtensions(entity); return super.save(entity); } }
- 自定义
RepositoryFactoryBean,在创建SimpleCustomRepository实例时传入依赖:
public class CustomCouchbaseRepositoryFactoryBean<T extends Repository<S, ID>, S, ID> extends CouchbaseRepositoryFactoryBean<T, S, ID> { private ExtensionHelper extensionHelper; // FactoryBean是Spring管理的Bean,这里@Autowired有效 @Autowired public void setExtensionHelper(ExtensionHelper extensionHelper) { this.extensionHelper = extensionHelper; } @Override protected RepositoryFactorySupport createRepositoryFactory(CouchbaseOperations operations) { return new CustomCouchbaseRepositoryFactory(operations, extensionHelper); } private static class CustomCouchbaseRepositoryFactory extends CouchbaseRepositoryFactory { private final ExtensionHelper extensionHelper; public CustomCouchbaseRepositoryFactory(CouchbaseOperations operations, ExtensionHelper extensionHelper) { super(operations); this.extensionHelper = extensionHelper; } @Override protected RepositoryComposition.RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata) { RepositoryComposition.RepositoryFragments fragments = super.getRepositoryFragments(metadata); // 给目标Repository接口附加自定义实现 if (SimpleCustomRepository.class.isAssignableFrom(metadata.getRepositoryInterface())) { CouchbaseEntityInformation<?, String> entityInfo = getEntityInformation(metadata.getDomainType()); SimpleCustomRepository<?, ?> customRepo = new SimpleCustomRepository<>(entityInfo, getCouchbaseOperations(), metadata.getRepositoryInterface(), extensionHelper); fragments = fragments.append(RepositoryFragment.implemented(customRepo)); } return fragments; } } }
- 在Spring配置类中指定使用自定义FactoryBean:
@Configuration @EnableCouchbaseRepositories(repositoryFactoryBeanClass = CustomCouchbaseRepositoryFactoryBean.class) public class CouchbaseConfig { // 其他Couchbase相关配置... }
方案二:实现ApplicationContextAware手动获取Bean
如果觉得方案一步骤繁琐,可以让SimpleCustomRepository实现ApplicationContextAware接口,直接从Spring上下文获取ExtensionHelper实例:
public class SimpleCustomRepository<T, ID> extends SimpleCouchbaseRepository<T, ID> implements ApplicationContextAware { private static ExtensionHelper extensionHelper; public SimpleCustomRepository(CouchbaseEntityInformation<T, String> entityInformation, CouchbaseOperations couchbaseOperations, Class<?> repositoryInterface) { super(entityInformation, couchbaseOperations, repositoryInterface); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // 从Spring上下文获取ExtensionHelper实例 extensionHelper = applicationContext.getBean(ExtensionHelper.class); } @Override public <S extends T> S save(S entity) { extensionHelper.applyExtensions(entity); return super.save(entity); } }
这里用静态字段是因为框架可能多次创建Repository实例,静态字段能保证所有实例共享同一个ExtensionHelper实例。
前置检查
你提到ExtensionHelper标注了@Component但不是标准Spring Bean,可能是它没被Spring扫描到。先确保:
@ComponentScan的扫描范围包含ExtensionHelper所在包;- 或者手动通过
@Bean将其注册到容器:
@Configuration public class BeanConfig { @Bean public ExtensionHelper extensionHelper() { return new ExtensionHelper(); } }
只有ExtensionHelper本身是Spring容器中的Bean,上面的注入方案才能生效。
内容的提问来源于stack exchange,提问作者Mortova
相关产品推荐
相关产品推荐

