본문 바로가기

백앤드 개발/Java & Spring

[Spring boot] 프로젝트 환경 설정과 Spring 어플리케이션 구조

1. 프로젝트 생성 및 동작 확인

1) 사전 준비 환경: Java11, IntelliJ

2) 스프링 스타터 사이트에서 프로젝트 생성  https://start.spring.io/

Project: Gradle - Groovy Project
Spring Boot: 2.7.17 (23.10.27 기준 Java 11 지원)
Language: Java
Packaging: Jar
Java: 11
groupId: hello
artifactId: hello-spring
Dependencies: Spring Web, Thymeleaf

3) 메인 클래스 실행

4) 빌드

빌드란 소스코드를 실행가능한 파일로 만드는 과정을 의미

현업에서 배포시 실행 파일만 서버에 넣고 $ java -jar.exe 로 실행

# 1. 디렉토리 이동 후 build
$ ./gradlew.bat build

# 2. 실행 확인
$ cd build/libs
$ java -jar hello-spring-0.0.1-SNAPSHOT.jar

# 3. 서버 배포시 파일만 복사해 서버에 넣고 명령어 실행
$ java -jar.exe

 

 

Execution failed for task ':compileJava'. 

메인 메소드 실행 또는 프로젝트 빌드할 때, 프로젝트 버전이 안맞을 경우 발생

1) File > Project Settings > Project > Project SDK: java 11로 설정

2) File > Settings > Build Tools > Gradle: java 11로 설정

3) File > Settings > Compiler > Java Compiler> Project bytecode version: 11로 설정

4) 환경 변JAVA_HOME, PATH 경로가 올바르게 설정되어 있는지 확인

5) IntelliJ 재시작

 

 

2. MVC 모델

1) Model: 화면에 필요한 데이터 관리. DB 에서 데이터를 가공.

2) Controller: Model- View 상호 작용 관리, url 관리, 화면에 뿌려질 데이터 전달, 

@Controller // Controller 명시
public class HelloController {

	// 1. 템플릿 반환
    @GetMapping("hello-mvc") // http://localhost:8080/hello-mvc?name=spring!
    // 1) get 방식으로 URL 로부터 name 값 가져 오기
    public String helloMvc(@RequestParam(value = "name") String name, Model model) {

        // 2) 전달할 모델에 name 추가하기
        model.addAttribute("name", name);

        // 3) 템플릿 반환: resources/templates/hello-template.html 반환
        return "hello-template";
    }
    
    
    // 2. JSON 반환
    @GetMapping("hello-api")
    @ResponseBody // ResponseBody 태그 후 객체 반환시, json으로 반환됨
    public Hello helloApi(@RequestParam("name") String name) {
            Hello hello = new Hello();
            hello.setName(name);
            return hello;
        }
        
        }
}

 

3) View: 화면 관련, 사용자 인터페이스 관리

<!-- resources/templates/hello-template.html  -->

<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello ' + ${name}">hello!</p>
</body>
</html>

 

 

3. 웹 어플리케이션 설계

1) Domain: 비즈니스 도메인 객체 설계

- Member 객체 정의: 테이블 필드 선언, Getter & Setter 정의

2) Repository: Domain 객체를 DB에서 관리, 개발자 스럽게 설계

- MemberRepository interface 정의: Member 객체에서 사용할 메서드 명시, 기능 명시

- MemoryMemberRepository 정의: DB 액세스, 인터페이스 상속 받아 CRUD 메소드 구현

3) Service: 비즈니스 로직 구현 (회원가입, 전체 회원 조회 등), 트랜잭션 관리, API 앤드포인트 구현,

리포지토리 선언 및 의존성 주입 (재사용성 증가 및 테스트 용이)

- MemberService: MemoryMemberRepository 가 아닌 MemberRepository 객체를 선언해 DI (외부 주입) 사용하도록 구현

 

 

4. 테스트 케이스

기능을 테스트 할 때마다 빌드 할 경우 오래 걸리고 반복 실행이 어렵기 때문에 junit 으로 테스트

실무에선 테스트 툴에서 오류 발생시 다음 단계로 못넘어가게 막기도 함

클래스 전체를 돌려 전체 클래스를 테스트할 수도 있음

테스트는 빌드 되지 않으므로 메소드 명은 과감하게 한글로 바꿔도됨

class MemberServiceTest {

// 1. 테스트에 사용될 Repository 와 Service 선언
 MemberService memberService;
 MemoryMemberRepository memberRepository;
 
 // 2. @BeforeEach: 각 테스트 실행전 호출. 테스트 간 영향이 없도록 새로운 객체 생성
 @BeforeEach
 public void beforeEach() {
 memberRepository = new MemoryMemberRepository();
 memberService = new MemberService(memberRepository);
 }
 
 // 4. @AfterEach: 각 테스트 실행후 호출. 데이터 클리어
 @AfterEach
 public void afterEach() {
 memberRepository.clearStore();
 }
 
 // 3. @Test: JUnit 테스트 정의
 @Test
 public void 회원가입() throws Exception {
 
 //Given
 Member member = new Member();
 member.setName("hello");
 
 //When
 Long saveId = memberService.join(member);
 
 //Then
 Member findMember = memberRepository.findById(saveId).get();
 assertEquals(member.getName(), findMember.getName());
 }
 
 
 @Test
 public void 중복_회원_예외() throws Exception {
 
 //Given
 Member member1 = new Member();
 member1.setName("spring");
 Member member2 = new Member();
 member2.setName("spring");
 
 //When
 memberService.join(member1);
 IllegalStateException e = assertThrows(IllegalStateException.class,
 () -> memberService.join(member2));//예외가 발생해야 한다.
 assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다.");
 }
}

 

 

5. 컴포넌트 스캔과 의존 관계 설정

1. 스프링 빈에서는 컨트롤러-서비스-리포지토리 간 의존 관계를 관리.

1. 컨트롤러는 서비스에 의존하고 서비스는 리포지토리를 의존.

2. 컨트롤러에서 @Controller  선언, 서비스에서 @Service 선언 후 생성자에서 @Autowired 를 선언하면 

스프링에서 컨트롤러-서비스 간 의존 관계를 설정.

마찬가지로 @Repository를 통해 서비스-리포지토리 간 의존관계를 설정.

3. 이처럼 객체 의존 관계를 외부에서 넣어주는 것을 'DI, 의존성 주입' 이라고 함.

4. 스프링 빈은 어노테이션이 아닌 config 파일 내에서도 직접 관리할 수 있음.

 

 

5. 기타 코멘트

1) gradle: 웹서버, 테스트 프레임워크, MVC 기능을 가진 다양한 스프링 부트 라이브러리 지원

2) 실무에선 log 파일로 출력 권장. 가급적이면 System.out.prin(); 사용을 지양.

3) Optional 데이터타입: Generics으로 명시된 타입 외에 null 반환 가능

4) Optional.ofNullable: 값이 있을수도 없을 수도 있음을 명시

5) TDD: 테스트 주도 개발, 각 주기마다 테스트 케이스 작성 후 해당 테스트를 통과시키는 코드를 작성하는 방식

6) 테스트 관련해서는 깊이 있게 공부하는 것을 권장

7) 빈(Bean): 스프링에서 관리되는 객체

 

참조: 

1) 자바 설치

https://velog.io/@sqk8657/%EC%9E%90%EB%B0%94JAVA-11-%EC%84%A4%EC%B9%98-%EB%B0%8F-%ED%99%98%EA%B2%BD%EC%84%A4%EC%A0%95-%EC%9E%90%EB%B0%94-11-%ED%99%98%EA%B2%BD-%EB%B3%80%EC%88%98

 

자바(JAVA) 11 설치 및 환경설정 | 자바 11 환경 변수

자바로 코딩 공부를 하려면 개발 할 수 있는 환경을 만들어 주어야 한다. 그 순서를 먼저 작성하자면JAVA SE JDK 설치 -> JAVA 환경 변수 설정 -> IDE 설치 이렇게 볼 수 있겠다. 이 포스팅은 자바로 개

velog.io

2) 스프링 관련

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard