@Primary JpaRepository不用于@Autowired

时间:2018-04-21 07:53:37

标签: java spring spring-data spring-data-jpa

我有最简单的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添加到配置的私有成员并将其返回,但由于与上述相同的原因而无法正常工作。

1 个答案:

答案 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)来提供更复杂的方法来决定您要使用的实现。