是否可以在不使用@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> {
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> {