본문 바로가기

WINK-(Web & App)/Spring Boot 스터디

[Spring Boot 스터디] 조현상 #3 주차 - 섹션 4,5

반응형

이번 주차에는 스프링 빈과 의존 관계 와 회원관리예제를 통해서 웹MVC 개발를 배워보았다.

 

우선 스프링 빈 의존 관계란 controller - service - repository 를 서로 연결 시켜주는 것을 말하는데

그동안 우리는 예를 들어 service 와 repository 를 연결시키려면 new 객체를 생성해줘서 연결 시켜보이도록 기능을 만들었었다.

근데 new 로 객체를 생성해서 만들어질 경우 서로 다른 repository를 받을 수 있고? 와 같은 문제가 있었는데 이번 시간에 이 문제를 해결하고자 하나의 repository를 가르키도록 의존관계를 배웠다.

 

우선 의존 관계는 컴포넌트 스캔으로 자동 의존관계 설정 방법이 있고 자바 코드로 직접 스프링 빈 등록하는 방법이 있다.

 

먼저 컴포넌트 스캔 의존관계 설정 방법은

컨트롤러에 @Controller 를 쓰고 서비스에는 @Service , 그리고 래포지토리에는 @Repository를 써놓은다.

위와 같이 써놓는 이유는 Spring이 뭐가 컨트롤러이고 뭐가 서비스인지 구분하기 위해서 써놓는다고 한다.

안 써놓을 경우에는 Spring이 구분하지 못해서 오류가 난다고 한다.

 

그 다음에 이전 new 처럼 연결 시켜야 되는 부분에 @Autowired 를 써주면 된다.

그래서 우리는 controller - > service  그리고 service - > repository 연결시켜줘야 되기 때문에

controller 와 service 에 @Autowired 를 써주면 끝이다.

 

그 다음 자바 코드로 직접 스프링 빈 등록하는 방법은

service 디렉토리 안에 SpringConfig 클래스를 만들어준다. 

@Configuration
public class SpringConfig {
    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository(){
        return new MemoryMemberRepository();
    }
}

 

그리고 위 처럼 연결 시켜줘야 되는 부분들을 @Bean 과  함께 써주고 위에는 @Configuration 을 써준다.

컨트롤러에서 서비스가 필요하니까 MemberService 를 만들어주었고

MemberService는 만들 때 MemberRepository 가 필요하니까 MemberRepository를 만들어주었다.

 

그러면 자바 코드로 직접 스프링 빈 등록하는 방법보다 컴포넌트 스캔을 통해서 의존관계를 만들어주는 것이 더 편하지 않냐라고 생각할 수 있는데 자바 코드로 직접 스프링 빈을 등록하는 경우는 앞서서 강의를 진행될 때 계속해서 의존 관계가 바뀔 경우가 많아질텐데 그 때마다 다른 곳에 바꿔줄 필요 없이 SpringConfig 클래스 안에서 바꿔주기만 하면 되기 때문에 편리할 수 있다.

 

 

다음으로는 회원관리예제를 통해서 웹MVC 개발 이다.

 

과정 순서는 홈 화면 추가 -> 회원등록 -> 회원조회 순서다.

 

우리가 전에 배웠을 때는 static 에서 index.html 을 만들어주면 local 8000으로 접속했을 때 index 파일이 자동으로 뜨게 된다고 배웠었는데 이 경우는 컨트롤러에서  @GetMapping("/") 이 없을 때 만들어주는 것이다.

 

이번에는 홈 화면을 만들어주어야 되기 때문에 controller 디렉토리 안에 HomeController 클래스를 만들어주었다.

@Controller
public class HomeController {
    @GetMapping("/")
    public String home(){
        return "home";
    }
}

Spring이 시작되면 컨트롤러를 한 번씩 읽게 되는데 이 때 @GetMapping("/")  을 읽게 되면서 local home에 뭐가 나갈지 정해지게 되는 것이다. 이처럼 home 화면에 무언가 나가게 된다면 index는 후순위이기 때문에 적용되지 않는다.

그리고 무엇이 나갈지는 return 값으로 정해줄 수 있다.

 

우리는 return 값으로 home을 선택했기 때문에 templates 안에 home.html 을 만들었다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class = "container">
    <div>
      <h1>Hello Spring</h1>
        <p>회원 기능</p>
        <p>
            <a href="/members/new">회원 가입</a>
            <a href="/members">회원 목록</a>
        </p>
    </div>
</div>
</body>
</html>

그리고 home.html 에 회원 가입과 회원 목록 링크를 다음과 같이 만들었다. href 를 통해서 링크를 눌렀을 때 다음 주소로 이동하게 될 것인데 이를 받는 controller 안에 MemberController 클래스를 만들어주었다.

 

@Controller
public class MemberController {
    private final MemberService memberService;
    @Autowired
    public MemberController(MemberService memberService){
        this.memberService = memberService;
    }
    @GetMapping("/members/new")
    public String createForm(){
        return "members/createMemberForm";
    }
    @PostMapping("/members/new")
    public String create(MemberForm form){
        Member member = new Member();
        member.setName(form.getName());

        memberService.join(member);

        return "redirect:/";
    }
}

여기서 보면 @GetMapping 과 @PostMapping 두 가지가 있는데

먼저    @GetMapping("/members/new")  은 아까 회원가입 링크를 클릭했을 때 받아서 members/createMemberForm html 을 보여주도록 만드는 것이고 

 @PostMapping("/members/new") 은 craeteMemberForm html 안에 있는 form 태그에 action = "/members/new" 때문이다.

form 태그는 method 가 post 형식이여서 form 태그 안에 input 을 눌렀을 경우 /members/new 가 post 형식으로 전달이 된다. 이 때 @PostMapping("/members/new") 가 잡는 것이다. 

여기서 중요한 점은 post 로 날라갈 때 input 안에 있는 값이 key로 작동되기 때문에 form.getName() key 값을 알 수 있다.

 

조회 방법은 thymeleaf 를 통해서 th:each = "memeber : ${members}" 처럼 th:each 와 th:text를 쓰면 for 문처럼 여러개의 태그들을 만들 수 있다.

이것은 memberService 에서 join을 통해 들어온 값들을 findMembers() 를 통해서 List 형태로 뽑은 뒤 mode 에 addAttribute 로 넣을 수 있다.

반응형