의존관계
스프링 빈을 등록하고 의존관계를 설정하는 방법을 알아보자.
@Componenet를 사용하여 컴포넌트 스캔으로 자동 의존관계를 설정하는 방법과
자바 코드로 직접 스프링 빈을 등록하는 방법이 있다.
이제 컨트롤러를 사용하여 페이지를 보여주어야 하고 그 컨트롤러는 학생 서비스 객체를 이용해야 한다.
이 상황에서 컨트롤러에 서비스를 주입을 해주어야 하는데 그 과정을 살펴보자.
우선 컨트롤러를 만들어보자
이렇게 StuController가 생성이 될 때 @Autowired를 이용해 의존관계를 주입해주었다.
생성자에 @Autowired가 있으면 연관된 객체를 spring이 찾아서 넣어준다.
하지만 저렇게 빨간줄이 뜨는 것을 볼 수 있는데, spring이 실행될 때 memberService가 없기 때문이다.
따라서 이럴 때에는 의존되는 memberService도 스프링 빈으로 등록을 해주어야 한다.
(@Controller가 있으면 spring에 자동으로 등록이 된다.)
서비스에도 이렇게 @Service annotation을 달아준다.
여기에도 의존관계를 주입해주어야 하는 부분에서 등록이 되어 있지 않기 때문에 빨간 줄이 뜨는 것을 볼 수 있다.
여기도 다시 리포지토리를 찾아서 @Repository annotation을 달아주자.
@Controller, @Service, @Repository에 해당하는 annotation들은 @Component 를 포함하기 때문에 등록이 된다.
리포지토리까지 annotation을 달아주면
memberController -> memberService -> memberRepository 로 스프링에 의존관계가 설정이 된다.
직접 자바코드를 사용하여 등록을 하려면
@Bean annotation을 사용하여 Configuration을 해주는 객체를 생성해주면 된다.
웹 MVC 개발
이제 웹 페이지를 만들어보자
우선 관련 controller를 만든다
기본 페이지 관련 Controller와 html
package spring_practice.spring_practice.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/")
public String home(){
return "home";
}
}
localhost에 들어가면 바로 home.html로 보내준다.
home.html이다.
<html xmlns:th="http://thymeleaf.org">
<head>
<title>학생 관리</title>
</head>
<body>
<div class="container">
<div>
<h1>학생 관리 프로그램</h1>
<p>회원 기능</p>
<p>
<a href="/student/new">신입생 등록</a>
<a href="/student">학생 리스트</a>
</p>
</div>
</div>
</body>
</html>
신입생 등록 컨트롤러이다.
package spring_practice.spring_practice.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import spring_practice.spring_practice.service.MemberService;
@Controller
public class StuController {
private final MemberService memberService;
@Autowired
public StuController(MemberService memberService){
this.memberService = memberService;
}
@GetMapping("/student/new")
public String createForm(){
return "student/createStuForm";
}
}
만들었던 Controller에 @GetMapping annotation으로 해당 주소에 접근하면 student/createStuForm.html을 열어주는 메서드를 생성하고
<!DOCTYPE HTML>
<body>
<div class="container">
<form action="/student/new" method="post">
<div class = "form-group">
<label form="name">이름</label>
<input type="text" id="name" name="name" placeholder="이름을 입력하세요">
</div>
<button type="submit">신입생 등록</button>
</form>
</div>
</body>
그리고 Controller와 같은 패키지에
package spring_practice.spring_practice.controller;
public class StuForm {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
폼 관련 객체를 생성을 해준다.
이제 이 폼을 사용하여 등록하는 기능을 구현하자, @PostMapping을 사용하여 해당 페이지에서 작동하게 만들고
return redirect:/으로 home으로 보내준다.
package spring_practice.spring_practice.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import spring_practice.spring_practice.domain.Member;
import spring_practice.spring_practice.service.MemberService;
@Controller
public class StuController {
private final MemberService memberService;
@Autowired
public StuController(MemberService memberService){
this.memberService = memberService;
}
@GetMapping("/student/new")
public String createForm(){
return "student/createStuForm";
}
@PostMapping("/student/new")
public String create(StuForm form){
Member member = new Member();
member.setName(form.getName());
memberService.join(member);
return "redirect:/";
}
}
이렇게만 하고 실행을 해보면
이런 home 페이지와
이런 신입생 등록페이지가 만들어지고 신입생 등록 버튼을 누르면 home 페이지로 이동하게 된다.
이제 조회기능을 추가하자, 컨트롤러에
@GetMapping("student")
public String list(Model model){
List<Member> students = memberService.findMembers();
model.addAttribute("students", students);
return "student/studentList";
}
이런 메서드를 추가하여 memberService에서 모든 학생 정보를 가져온 후 model의 속성에 추가해서 student/studentList.html로 넘겨준 후
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
<div>
<table>
<thead>
<tr>
<th>#</th>
<th>name</th>
</tr>
</thead>
<tbody>
<tr th:each="student : ${students}">
<td th:text="${student.getStudentId()}"></td>
<td th:text="${student.getName()}"></td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
이렇게 each로 돌면서 모든 학생들을 보여지게 한다.
이러면
이렇게 페이지가 잘 보여지는 것을 확인 할 수 있다.