我正在学习有关Spring Boot和JPA,Spring Data Rest,H2数据库的知识,并且找到了一个教程。我试图理解它,这是一个简单的例子,但我不明白。为什么没有必要将@Repository
或@Component
放入AlienRepo类中?
回购对象被注入到 AlienController 类中,从以前的教程中我知道您需要使用@Component
或@Repository
。我认为必须使用此注释。
控制器:
package com.dgs.springbootjpa.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.dgs.springbootjpa.dao.AlienRepo;
import com.dgs.springbootjpa.model.Alien;
@Controller
public class AlienController {
@Autowired
AlienRepo repo;
@RequestMapping("/")
public String home() {
return "home.jsp";
}
@RequestMapping("/addAlien")
public String addAlien(Alien alien) {
repo.save(alien);
return "home.jsp";
}
}
POJO:
package com.dgs.springbootjpa.model;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Alien {
@Id
private int aid;
private String aname;
public int getAid() {
return aid;
}
public void setAid(int aid) {
this.aid = aid;
}
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
@Override
public String toString() {
return "Alien [aid=" + aid + ", aname=" + aname + "]";
}
}
dao接口:
package com.dgs.springbootjpa.dao;
import org.springframework.data.repository.CrudRepository;
import com.dgs.springbootjpa.model.Alien;
public interface AlienRepo extends CrudRepository<Alien, Integer> {
}
您可以看到,在 AlienRepo 界面中没有@Repository
或@Component
,并且代码正在成功运行。
谢谢!
更新--------------------------------------------- < / p>
我想从数据库中获取数据,然后添加以下代码。我想问你为什么@RequestParam不是强制性的?如果我删除@RequestParam,则应用程序成功运行。
@RequestMapping("/getAlien")
public ModelAndView addAlien(@RequestParam int aid) {
ModelAndView mv = new ModelAndView("showAlien");
Alien alien = repo.findById(aid).orElse(new Alien());
mv.addObject(alien);
return mv;
}
答案 0 :(得分:4)
您是否注意到,CrudRepository有@NoRepositoryBean注释,此注释使CrudRepository成为中间接口。基本上增加了一个中间接口 衍生存储库的常规功能。
如果有任何用@NoRepositoryBean注释的类,Spring Data在运行时不会创建实例。因为它是中间类,所以创建它是为派生类添加功能。
如果扩展具有@NoRepositoryBean的接口而派生接口没有@NoRepositoryBean,Spring会知道您正在尝试在真正的Repository接口中使用该功能,因此添加@Repository注解很冗长。
编辑:为什么@RequestParam不是必需的?
在the offical documentation中,您可以看到“控制器方法参数”表,该表的最后一行显示:
其他任何论点:
如果方法参数与以上任何参数都不匹配,则默认情况下,如果它是由@RequestParam确定的简单类型,则将其解析为BeanUtils#isSimpleProperty,否则将其解析为@ModelAttribute。
因此,如果您省略了“ Controller Method Argument”的注释,并且您未编写诸如@MatrixVariable,@PathVariable或@RequestParam之类的内容。 默认为@RequestParam。但是出于可读性考虑,我建议编写@RequestParam。
您可以看到@RequestParam与@Repository的原因有所不同。
@Repository是冗长的,而@RequestParam不是。 @RequestParam
仅是默认设置。编写@RequestParam有助于提高可读性。
答案 1 :(得分:2)
@Component
和@Repository
可以在类中用作Spring Bean。但是,AlienRepo
不是类,它是扩展Spring Data接口的接口。 Spring Data不使用注释,它通过扫描类路径并查看接口的层次结构以查看Spring Data接口是否已扩展来检测接口。如果是这种情况,它将在运行时为每个接口创建一个实现,然后将其作为Spring Bean添加到应用程序上下文中。这就是为什么在Spring Data接口上不需要任何注释的原因。
答案 2 :(得分:2)
您的JdbcBatchItemWriter
带来了@SpringBootApplication
批注的作用:
@EnableAutoConfiguration
此注释将猜测并自动配置bean。
Spring Data的JPA存储库的自动配置。 当在上下文中配置了DataSource类型的Bean,Spring Data JPA JpaRepository类型在类路径上并且没有其他现有的JpaRepository配置时激活。
实际上,自动配置等效于使用EnableJpaRepositories批注启用JPA存储库。
此配置类将在Hibernate自动配置后激活。
@EnableAutoConfiguration
public @interface SpringBootApplication
添加data-jpa依赖项时,将触发public class JpaRepositoriesAutoConfiguration {
}
,并为您的应用带来JpaRepositoriesAutoConfiguration
批注的作用
Your repository then auto-configured:
Spring数据存储库通常从Repository或CrudRepository接口扩展。如果使用自动配置,则会从包含主配置类(用@EnableAutoConfiguration或@SpringBootApplication注释的主配置类)的包中搜索存储库。
答案 3 :(得分:1)
您的AlienRepo
类扩展了CrudRepository
,因此Spring将能够浏览配置中指定的包并找到存储库。
请注意,如果只有一个构造函数@Autowired
,则可以删除AlienController(AlienRepo)
,Spring也可以弄清楚。