我有最简单的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
在Configuration中的-带注释的方法中实例化存储库。我会将一个添加@Autowired
到配置的私有成员中并返回它,但是由于上述相同的原因,它将无法正常工作。
对于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)提供更复杂的决策方法,您要使用哪个实现。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句