@Autowired如何知道JPA Repository该怎样实现?

我是一个JAVA初学者
在看到JPA基础的时候,对于继承JpaRepository接口后,直接使用@Autowird即可自动获取相关查询方法感到很神奇,如下:
定义一个repository接口,继承JpaRepository

@Repository

public interface UserRepository extends JpaRepository<User, Long> {

}

直接可以使用:

@SpringBootTest

@RunWith(SpringRunner.class)

public class UserRepositoryTest {

@Autowired

private UserRepository userRepository;

private Long id;

@Before

public void setUp() {

assertNotNull(userRepository);

User user = new User("SnailClimb", 23);

User savedUser = userRepository.saveAndFlush(user);// 更新 user 对象的姓名

savedUser.setName("UpdatedName");

userRepository.save(savedUser);

id = savedUser.getId();

}

我并没有给容器中注入相关Bean,@Autowired是如何知道该怎样正确实现这些方法的?


增加问题描述:

感谢大家的回答,但可能我没有很清晰的描述好我的问题:

其实我想知道的是Spring是如何通过 Repository接口类型(在UserRepository接口类型上注明了@Autowired),来知道如何注入,注入哪一个实现类的。

比如:

按照Spring自己的用法,我在一个类上注明一个@Component,就表明这是个Bean,那么Spring可以很容易的通过反射找到这个类实例化并注册到IoC容器中,然后在使用的地方注入这个对象即可。

但是我在一个接口上注明@Component,系统就不应该知道这个接口的方法如何实现。应该是先绑定一个接口到一个已经实现接口的类(我没有找到这一步,所以不太理解注入机制),然后系统去实例化这个接口实现类。但是我不是很清楚Repository接口是如何绑定到具体实现的。

不知是否表达清楚,大概是这个意思。


回答:

你问的其实是Spring IOC容器的原理

  1. springboot启动的时候会默认扫码启动类当前目录和子目录下,带有@Component注解的类(包括@Controller、@RestController、@Service等等都是)
  2. 把扫描到的组件类实例化以后放入容器中,就是bean
  3. 在依赖某个bean的类实例化时,把带有@Autowired注解的属性、构造方法、setter方法注入bean完成自动装配

另外再说两点

  1. 你那个@Repository注解其实是不需要的,只要继承了JpaRepository都算repository,因为JpaRepository自带了一个组件注解
  2. spring4和5版本推荐构造器注入(并且这个方式可以省略@Autowired注解),最核心的优点就是自行实例化具体的类时,不会因为没有注入bean而报错

有一个对应的repository工厂类,根据你repository接口的定义和传入的实体类,自动代理实现了一个基于模板仓库类中的方法+你自定义方法的类的实例放到容器中

相关的两个类,供参考:
https://docs.spring.io/spring...

https://docs.spring.io/spring...


回答:

因为@Repository注解里使用了@Component的
类似的还有@Service、@Controller等


回答:

cglib(或者其他工具)运行期根据注解参数等等生成了具体的类
mybatis的mapper接口同理

以上是 @Autowired如何知道JPA Repository该怎样实现? 的全部内容, 来源链接: utcz.com/p/944422.html

回到顶部