생성자에 @Autowired 가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어줌
즉, 외부에서 객체 의존 관계를 넣어주는 것
💡의존성 주입 3가지 방법
의존성을 변경할 일이 거의 없으므로 객체 생성 시 한 번만 주입하고 수정할 수 없는 생성자 주입이 안전하며, setter 주입은 객체를 수정할 가능성을 열어두어 위험할 수 있다.
Bean(빈) : 스프링 프레임워크에서 관리되는 객체
IoC 컨테이너에 빈으로 등록이 되어야 의존성 주입 가능
👉 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다. (유일하게 하나만 등록해서 공유한다.) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다.
설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.
@Component 애노테이션이 있으면 스프링 빈으로 자동 등록됨
‼️ @Controller, @Service, @Repository 는 @Component 을 포함
🖥️ MemberSerive
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository){
this.memberRepository = memberRepository;
}
정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록해야한다.
ex : memberRepository라는 인터페이스가 있고, DB 또는 메모리에 데이터를 저장하는 두가지의 구현체가 있다고 가정하자. MemberService는 인터페이스에만 의존하고 구현체에는 의존하지 않는다. 즉, 메모리에서 DB 연결로 바꾸고 싶을 때 MemberService는 그대로 두고 SpringConfig에서 DB 구현체를 return해주기만 하면 되는 것이다.
🖥️ SpringConfig
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
🖥️ HomeController
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "home";
}
}
home.html 파일로 접근함 🖥️ MemberController
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
@GetMapping(value = "/members/new")
public String createForm() {
return "members/createMemberForm";
}
}
이후, 회원 등록 폼 HTML인 createMemberForm.html에서 회원이 이름을 작성하면, MemberForm 객체에서 그 데이터를 전달 받아 다시 컨트롤러로 전달해준다.
🖥️ MemberController
@PostMapping(value = "/members/new")
public String create(MemberForm form) {
Member member = new Member();
member.setName(form.getName());
memberService.join(member);
return "redirect:/";
}
전달 받은 Memberform 객체에서 getName()을 통해 회원이 등록한 이름을 얻어 새로운 member 객체에 저장함. 이 member 객체를 memberService에 전달하여 join하도록 한다.
redirect:/는 "/" URL로 이동하라는 의미🖥️ MemberController
@GetMapping(value = "/members")
public String list(Model model) {
List<Member> members = memberService.findMembers();
model.addAttribute("members", members);
return "members/memberList";
}
Model에 데이터를 담아 뷰로 전달함addAttribute("members", members)를 통해 members라는 키로 조회한 회원 리스트 데이터를 HTML로 전달함 🖥️ memberList.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
<div>
<table>
<thead>
<tr>
<th>#</th>
<th>이름</th>
</tr>
</thead>
<tbody>
<tr th:each="member : ${members}">
<td th:text="${member.id}"></td>
<td th:text="${member.name}"></td>
</tr>
</tbody>
</table>
</div>
</div> <!-- /container -->
</body>
</html>