是否可以在不使用@Repository 或@Bean 的情况下向Container 注册?

Is it possible to register with Container without using @Repository or @Bean?

public interface AccountRepository extends CrudRepository<AccountDBModel, Long> {

  @Modifying
  @Query(value = PortfolioQuery.ACCOUNT_INSERT)
  void insert(@Param("exchangeId") Long exchangeId, @Param("name") String name, @Param("siteAccount") String siteAccount,
      @Param("memo") String memo, @Param("createdAt") Long createdAt, @Param("updatedAt") Long updatedAt,
      @Param("isActive") Boolean isActive);

  @Modifying
  @Query(value = PortfolioQuery.ACCOUNT_UPDATE)
  void update(@Param("id") Long id, @Param("exchangeId") Long exchangeId, @Param("name") String name,
      @Param("siteAccount") String siteAccount, @Param("memo") String memo, @Param("updatedAt") Long updatedAt,
      @Param("isActive") Boolean isActive);

  @Query
  Optional<AccountDBModel> findByName(@Param("name") String name);
}
@Service
public class AccountService {

  private final AccountRepository repository;

  @Autowired
  public AccountService(AccountRepository repository) {
    this.repository = repository;
  }

  public void postAccount(AccountBaseModel baseModel) throws Exception {
    Long now = System.currentTimeMillis();
    this.repository.insert(baseModel.getExchangeId(), baseModel.getName(), baseModel.getSiteAccount(),
        baseModel.getMemo(), now, now, baseModel.getIsActive());
  }
}
@SpringBootTest
class WaveBackofficeApiApplicationTests {

  @Autowired
  private ApplicationContext applicationContext;

  @Test
  public void contextLoads() throws Exception {
    if (applicationContext != null) {
      String[] beans = applicationContext.getBeanDefinitionNames();

      for (String bean : beans) {
        System.out.println("bean : " + bean);

      }
    }
  }
}

正如您在AccountRepository 接口中看到的,我没有在AccountRepository 接口中使用@Repository。

但是为什么在Spring容器中注册为bean?

没有其他 class 与 AppConfig 类似。

接口本身没有注册为bean。 spring 框架提供存储库 bean 的现有实现(默认实现是 class SimpleJpaRepository),它根据您在接口中提供的规范进行注入。这个特定的 class 具有 @Repository 注释,将被 spring 作为 bean 拾取。

简单概述:

@Repository
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID>  {
    // code
}

public interface MyRepository extends CrudRepository<T, ID> {}


@Service
public MyService() {
    @Autowired private MyRepository myRepository;
}

在上面的例子中,我们自己的repository接口扩展了CrudRepository,它有一个实现class名为SimpleJpaRepository(在框架中提供),SimpleJpaRepository被注册为一个bean。在 MyService 中,我们只是告诉我们想要一个 MyRepository 类型的 bean,Spring 将注入一个 SimpleJpaRepository 实例。

您创建了名为 AccountRepository 的接口并进行了扩展(因此 继承CrudRepository

现在只需在 CrudRepository 上执行 Ctrl + Left mouse click,您将在其中结束:

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
    <S extends T> S save(S entity);

    <S extends T> Iterable<S> saveAll(Iterable<S> entities);

    Optional<T> findById(ID id);

    boolean existsById(ID id);

    Iterable<T> findAll();

    Iterable<T> findAllById(Iterable<ID> ids);

    long count();

    void deleteById(ID id);

    void delete(T entity);

    void deleteAllById(Iterable<? extends ID> ids);

    void deleteAll(Iterable<? extends T> entities);

    void deleteAll();
}

Intellij 实际上让您有机会找到所有这些方法的实现,左侧带有向下箭头标记。

所以有一个巨大的 class 叫做 SimpleJpaRepository,它有所有的实现,实际的代码。

事情是...

SimpleJpaRepository.class 里面确实有 @Repository:

@Repository
@Transactional(
    readOnly = true
)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {