leehyeon-dv 님의 블로그

스프링 부트 3 코드&구조 이해하기 본문

spring/spring 이론

스프링 부트 3 코드&구조 이해하기

leehyeon-dv 2024. 12. 21. 19:25

목차

  1. @SpringBootApplication 이해하기
  2. @SpringBootApplication 의미 파악
  3. 프로젝트 이해
  4. 스프링에서의 계층
  5. 디렉터리 구성
  6. main 디렉터리 구성
  7. build.gradle에 의존성 추가하기
  8. 프레젠테이션, 서비스, 퍼시스턴스 계층 만들기
  9. 작동 확인하기
  10. 스프링 부트 요청-응답 과정 이해하기

1📌@SpringBootApplication 이해하기

//springBootDeveloperApplication.java

@SpringBootApplication
public class SpringbootDeveloperApplication {
	public static void main(String[] args) {
		SpringApplication.run(SpringbootDeveloperApplication.class, args);
	}

}

이 클래스는 자바의 main()메서드와 같은 역할을 한다

@SpringBootApplication 애너테이션을 추가하면 스프링 부트 사용에 필요한 기본 설정을 해준다 

SpringApplication.run() 메서드는 애플리케이션을 실행한다 

    1. 첫번째 인수 = 스프링부트 애플리케이션의 메인클래스로 사용할 클래스 

    2. 두번째 인수 = 커맨드 라인의 인수들 전달

 

2.📌@SpringBootApplication 의미 파악

ctrl 애너테이션을 눌러서 구성을 보면 

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration   //스프링 부트 관련설정
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    //사용자가 등록한 빈을 읽고 등록
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public ......
  • @SpringBootConfiguration = 스프링 부트 관련설정 애너테이션
  • @ConponentScan = 사용자가 빈을 읽고 등록하는 애너테이션 (@Component라는 애너테이션을 찾아 빈으로 등록)
@Configuration 설정 파일 등록
@Repository ORM 매핑
@Controller, @RestController 라우터
@Service 비지니스 로직

 

  • @EnableAutoConfiguration = 스프링 부트에서 자동 구성을 활성화하는 애너테이션

 

3.📌프로젝트 이해

  • TestController = 외부 요청을 분기해 적절한 서비스 클래스와 연결해 작업을 처리하고 값을 반환                                                             (어떤 요청인지 판단)
  • TestService = 데이터베이스 조작이나 비지니스 로직을 메서드 기반으로 처리                                                                                           (그 요청에 맞는 작업실행)
  • Member클래스로 구현한 클래스를 MemberRepository인터페이스가 실제 테이블과 매핑
  • 실직적인 데이터는 h2 데이터베이스에 쌓임

build.gradle에 앱 개발에 필요한 도구를 적으면 알아서 로딩해줌

  • JPA = 데이터베이스 연결 및 구현
  • lambok  = 클래스 메서드 구현 도우미
  • h2 = 인메모리 데이터베이스

 

4.📌스프링에서의 계층

  • 프레젠테이션계층 = HTTP요청을 받고 이 요청을 비지니스 계층으로 전송(컨트롤러가 이 계층역할을 함)
    • TestController클래스와 같은 것을 말하며 컨트롤러가 여러개 일 수 있음
  • 비지니스 계층 = 모든 비지니스 로직을 처리(서비스를 만들기위한 로직)
  • 퍼시스턴스 계층 = 모든 데이터베이스 관련로직 처리 , 이 과정에서 DAO 객체를 사용할 수도 있다 
    • DAO = 데이터베이스 계층과 상호작용하기위한 객체

 

5.📌디렉터리 구성

  • main = 실제코드 작성하는 공간, 프로젝트 실행에 필요한 소스코드나 리소스 파일은 모두 이 폴더 안에 있음
  • test = 프로젝트의 소스 코드를 테스트할 목적의 코드나 리소스 파일이 들어있음
  • build.gradle = 빌드를 설정하는 파일, 의존성이나 플러그인 설정 등과 같이 빌드에 필요한 설정을 할때 사용
  • settings.gradle = 빌드할 프로젝트의 정보를 설정하는 파일

 

6.📌main 디렉터리 구성

  • templates 디렉터리 = HTML과 같은 뷰 관련 파일을 넣음
  • static디렉터리 = JS, CSS, 이미지와 같은 정적 파일을 넣는 용도로 사용
  • application.yml = 스프링 부트 설정 ( 스프링 부트 서버가 실행되면 자동으로 로딩되는 파일)
    • 데이터베이스의 설정정보, 로깅설정 정보 등이 들어가거나 직접 설정 정의 시 사용

application.properties와 application.yml 차이

application.properties application.yml
간단한  설정파일에 적합 계층적구조로 가독성이 뛰어남
key-value형식으로 문법이 단순 복잡한 설정을 더 직관적으로 작성
초보자나 간단한 프로젝트 작성시 추천 설정이 많거나 계층구조 복잡할때, 
협업에서 가독성을 높일때 추천

 

 

7.📌build.gradle에 의존성 추가하기

스프링부트용 JPA인 스프링 데이터 JPA

로컬환경과 테스트환경에서 사용할 인메모리 데이터베이스인 H2

반복 메서드 작성작업을 줄여주는 라이브러리 롬복 추가

dependencies {
    ...
    
	implementation('org.springframework.boot:spring-boot-starter-data-jpa')
	runtimeOnly('com.h2database:h2')
	compileOnly('org.projectlombok:lombok')
	annotationProcessor('org.projectlombok:lombok')
}
  • implementation : 프로젝트 코드가 컴파일 시점과 런타임에 모두 해당 라이브러리를 필요로할때
  • testImplementation : 프로젝트의 테스트 코드를 컴파일하고 실행할 때만 필요한 의존성을 설정, 테스트코드에서만 사용
  • runtimeOnly : 런타임에만 필요한 의존성을 지정
  • compileOnly : 컴파일 시에만 필요 
  • annotationProcessor : 컴파일 시에 애너테이션을 처리할 때 사용하는 도구의 의존성 지정

8.📌프레젠테이션, 서비스, 퍼시스턴스 계층 만들기

 

TestController.java

@RestController
public class TestController {
    @Autowired
    TestService testService;

    @GetMapping("/test")
    public List<Member> getMembers() {
        List<Member> members = testService.getMembers();
        return members;
    }

}

 

 

TestService.java (같은 디렉토리에 만들기)

@Service
public class TestService {
    @Autowired
    MemberRepository memberRepository; //빈 주입

    public List<Member> getMembers() {
        return memberRepository.findAll(); //멤버 목록열기
    }
}

 

그림으로 표현하면 다음과 같다

 

이제 DB에 접근할때 사용할 객체인 Member DAO를 생성하고 실제 DB에 접근하는 코드를 작성한다

Member.java

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter
@Entity
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column( name = "id", updatable = false)
    private Long id;  //DB테이블의 id 컬럼과 매칭
    
    @Column(name = "name", nullable = false)
    private String name; //DB테이블의 name 컬럼과 매칭
}

 

이제 member 테이블과 Member 클래스를 매핑하는 코드 작성하기

MemberRepository.java 인터페이스 생성

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
}

 

 

9.📌작동 확인하기

현재는 인메모리 데이터 베이스를 사용해 애플리케이션을 새로 실행 시 마다 데이터가 사라져 불편하다

따라서 애플리케이션을 실행시에 원하는 데이터를 자동으로 넣는 작업을 하자 

resource파일에 data.sql을 만든다

INSERT INTO member (id, name) VALUES (1, 'user1');
INSERT INTO member (id, name) VALUES (2, 'user2');
INSERT INTO member (id, name) VALUES (3, 'user3');

 

application.yml 파일을 열어 아래 코드로 변경한다 

(show-sql , format_sql = 애플리케이션 실행과정에 데이터베이스에 쿼리할 일이 있으면 실행 구문을 모두 보여주는 옵션)

(defer-datasource-initialization : 애플리케이션을 실행 시에 테이블을 생성하고 data.sql파일에 있는 쿼리를 실행하도록하는 옵션)

 

기존에 만들어둔 application.yml을 열어 작성

spring:
  jpa:
    show-sql: true
    properties:
        hibernate:
            format_sql: true

    defer-datasource-initialization: true

전송 쿼리 확인 후 테이블 생성한 다음 data.sql 실행

 

서버를 실행해 create를 검색해보면 테이블이 만들어짐을 볼 수 있다

이제 HTTP로 요청 시도

포스트맨으로 (http://localhost:8080/test)입력하면 data.sql 파일로 작성한 데이터를 확인할 수 있다

 

결론(포스터맨에서 데이터를 보기까지의 과정

 

10.📌스프링 부트 요청-응답 과정 이해하기

  • /test GET요청 → 스프링부트 내로 이동
  • url 분석해 TestController가 /test라는 패스에 대한 GET요청을 처리할수 있는 getAllMembers()메서드를 가지고 있기 때문에 TestController에 GET요청 전달
  • getAllMembers() 메서드에서는 비지니스 계층과 퍼시스턴스 계층을 통하면서 필요한 데이터 가져옴
  • 뷰 리졸버가 템플릿엔진을 사용해 HTML 문서를 만들거나 JSON, XML데이터를 생성함
  • 결과 members를 return해 포스트맨에서 결과를 볼 수 있게 된다