我有最简单的Spring配置案例,所以我不知道为什么我不知道如何做到这一点。
我有一个界面
public interface UserService {
List<User> findAll();
}
有两个实现
@Component
public class SimpleUserService implements UserService {
private List<User> users = Arrays.asList(new User());
@Override
public List<User> findAll() {
return Collections.unmodifiableList(users);
}
}
和
@Repository
@Primary
public interface UserRepository extends JpaRepository<User, Integer>, UserService {
}
请注意,@Repository
标记为@Primary
,因此当我这样做时:
@RestController
public class SimpleUserController implements UserController {
@Autowired
private UserService userService;
@Override
@GetMapping("/users")
public List<User> getAllUsers() {
return userService.userResources;
}
}
它应该使用UserRepository
,不是吗?相反,我得到
com.studying.user.SimpleUserController中的字段userService需要一个bean,但是找到了2个:
UserDaoService:在文件[... \ SimpleUserService.class]中定义
userRepository:以null定义
我知道Spring创建了一个实际的类来实现存储库,所以我想这可能是问题,但有没有办法继续这样做?
作为一个额外的问题,我将如何创建两个配置,一个使用简单服务,另一个使用存储库?它不像我可以在配置中的@Bean
- 注释方法中实例化存储库。我将@Autowired
添加到配置的私有成员并将其返回,但由于与上述相同的原因而无法正常工作。
答案 0 :(得分:3)
对于Spring Data界面,您既不需要@Component
也不需要@Repository
。存储库由不同的Spring Data机制检测,而不是Spring本身的常规组件扫描。这也是您的@Primary
注释没有任何效果的原因。
解决方案可能如下所示:
public interface UserService {}
@Component
public class SimpleUserService implements UserService {}
@Component
public class JpaUserService implements UserService {
@Autowired
UserRepository userRepository
}
public interface UserRepository extends JpaRepository<User, Integer> {}
然后,您的存储库层与Spring Data存储库和服务层(使用存储库层)之间有明确的分离。您也不会混合常规的Spring bean注释和Spring Data存储库接口,这也将简化您的工作。
然后你可以将SimpleUserService
移动到测试源文件夹中(如果它只能用于单元测试),并将其标记为@Primary
。或者您可以使用@Conditional
注释(https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Conditional.html)来提供更复杂的方法来决定您要使用的实现。