스프링 부트 스타터를 이용하여 프로젝트 생성

https://start.spring.io/


Dependency

롬복(Lombok)

  • 자바 프로젝트 필수 라이브러리
  • 클래스에서 필수적으로 작성해야 하는 접근자 / 설정자
    • getter / setter, toString, equalsAndHashCode, 생성자
    • Constructor 등을 작성하지 않아도 된다.
  • 코드를 간결하게 사용할 수 있다.
  • 배포버전을 확인하고 결합이 있는지 확인해야 한다.

H2Database

  • 인-메모리(in-memory), 파일(file), TCP 지원 데이터베이스
  • JDBC url 설정으로 데이터베이스 작동방식 지정 가능
  • 스트링 부트 자동 구성으로 /h2-console h2 webconsole 제공
  • 로컬 개발환경에서 별도의 DB 설치 없이 빠른 프로토타이핑 지원
  • 필요에 따라 운영가능한 수준의 데이터베이스 활용 가능

구성설정

settings.gradle

rootProject.name = 'spring-boot'
  • 멀티 프로젝트 구성 시 사용
  • 하위 모듈 Include 시 사용
  • 프로젝트 이름
  • 하위 프로젝트 정의
  • 하위 프로젝트 설명

 


그래이들 래퍼(Wrapper)

  • Gradle Wrapper 생성 전에는, 개발자 각각이 Gradle을 다운받아 사용
    버전 차이로 인해 빌드 시 에러 발생
  • Jenkins도 Wrapper를 가지고 있는 프로젝트를 빌드하는 것을 기본속성으로 가지고 있다.
  • GRADLE_USER_HOME에 래퍼 파일이 있는지 확인하고 없으면 배포서버에서 내려받아 압축해제


Spring Boot Repackaging

unzip spring-boot-0.0.1-SNAPSHOT.jar
  • BOOT-INF/lib 하에 라이브러리 jar 파일이 존재
  • BOOT-INF/classes/static 하에 jsp, css, image 파일
  • BOOT-INF/classes/templates 하에 타임리프, 벨로시티, 그루비 템플릿 등
  • META-INF/MANIFEST.MF 자바 애플리케이션 압축 시의 기본스펙, 메인클래스 / 버전 

spring-boot-starter 구성

  • spring-boot-dependencies
    • 스프링 부트 배포버전에서 지원하는 각 라이브러리 모듈의 버전을 정의
  • spring-boot-autoconfigure
    • 스프링 부트 스타터의 라이브러리 모듈에 대한 자동구성
  • spring-boot-parent
    • 위에 언급된 두 모듈을 포함하고 있는 스프링 부트 최상위 모듈로써 스프링 부트 작동 핵심모듈
  • spring-boot-starters
  • spring-boot-starter-*/pom.xml

Spring-Framework

@Component 상속관계


@Bean vs @Component

  • @Bean - 남이 작성한 것
    • ‘스프링 IoC 컨테이너'에서 생명주기를 관리하는 객체
  • @Component - 내가 작성한 것

Dependency Injection

Dependency Injection을 사용하지 않은 경우


Dependency Injection을 사용한 경우


라이브러리 vs 프레임워크

  • 프레임워크는 라이브러리와 다르게 @AutoWired로 선언하여 사용 가능

Dependency Injection 방법

  • 생성자 주입 (권장)
    @Service
    public class BookServiceImpl implements BookService {
     private final BookRepository repository;
     public BookServiceImpl(BookRepository repository) {
     this.repository = repository;
     }
     // 코드 생략
    }​
  • 설정자 주입
    @Service
    public class BookServiceImpl implements BookService {
     private BookRepository repository;
     @Autowired
     public void setRepository(BookRepository repository) {
     this.repository = repository;
     }
     // 생략
    }​
  • @AutoWired
    @Service
    public class BookServiceImpl implements BookService {
     @Autowired
     private BookRepository repository;
     // 코드 생략
    }​

애플리케이션 계층 (Layerd Spring Application)


@Repository - Spring Data JPA

  • ORM (Object Relational Mapping)
    • 대부분의 개발언어를 플랫폼마다 제공
    • 객체로 관계형 데이터페이스를 관리
  • JPA (Java Persistence API)
    • 자바 객체정보를 영속화하는 중간 과정을 처리
    • 앤티티 객체를 저장 / 변경 / 삭제 하면 그에 해당하는 쿼리를 생성하고 실행

객체 모델링 저장


JpaRepository 인터페이스를 확장하여 사용


Spring Data JPA 작동원리


비즈니스 로직 구현에만 집중

  • 영속화 계층 @Repository 에서는 엔티티 관리만
  • 비즈니스 로직 구현은 도메인 영역에서
  • 서로 다른 도메인 사이의 연계는 서비스 계층 @Service 에서
  • 외부 요청에 대한 처리는 컨트롤러 계층 @Controller 에서

실습

package io.daseul.tacademy.springboot.domain;

import ...

@Getter
@Setter
@NoArgsConstructor
@Entity
public class Book extends AbstractPersistable<Long> {

    private String name;
    private String isbn13;
    private String isbn10;
}
package io.daseul.tacademy.springboot.domain;

import ...
public interface BookRepository extends JpaRepository<Book, Long> {
    List<Book> findByNameLike(String name);
}
package io.daseul.tacademy.springboot.domain;

import ...

@SpringBootTest
public class BookRepositoryTest {

    @Autowired
    BookRepository bookRepository;

    @Test
    void FindByNameLikeTest() {

        Book book = new Book();
        book.setName("1");
        book.setIsbn13("2");
        book.setIsbn10("3");

        Assertions.assertThat(book.isNew()).isTrue();
        bookRepository.save(book);

        Book book1 = bookRepository.findByNameLike("1%").get(0);
        Assertions.assertThat(book1.getIsbn10()).isEqualTo("3");
    }
}


@Service

  • 트랜잭션 (@Transactional) 관리영역
  • 서로 다른 도메인 연계(@Autowired) 작업 영역
  • @Controller, @Repository 사이의 중계

실습

package io.daseul.tacademy.springboot.service;

import ...

public interface BookService {
    Optional<Book> findById(Long id);
}
package io.daseul.tacademy.springboot.service;

import ...

import java.util.Optional;

@Service
@Transactional
public class BookServiceImpl implements BookService{
    private final BookRepository bookRepository;

    public BookServiceImpl(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }

    @Override
    public Optional<Book> findById(Long id) {
        return bookRepository.findById(id);
    }
}
package io.daseul.tacademy.springboot.service;

import ...


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class BookServiceTest {
    @Autowired
    BookService bookService;

    @Test(expected=RuntimeException.class)
    public void serviceTest() {
        Book book = new Book();
        bookService.findById(1L)
                .orElseThrow(() -> new RuntimeException("!!"));
    }
}

@Controller

  • DispatcherServlet에 등록된 @RequestMapping 호출
  • 템플릿 엔진이 렌더링할 뷰 페이지를 지정
  • 호출된 API에서 처리한 응답을 반환


@Controller 예외처리 (ExceptionHandler)

  • @ControllerAdvice 를 이용한 처리
@ControllerAdvice(annotations = {RestController.class})
@ResponseBody
public class GlobalRestControllerAdvice {
 @ExceptionHandler(BookNotFoundException.class)
 public ApiResponse<Void> handleException(Exception e) {
 log.error("Occurred Exception: {}", e);
 return ApiResponse.error(e.getMessage());
 }
}

REST API

  • 시스템의 자원에 대한 접근 및 제어를 제공하는 API
  • 자원 (Book) 에 대한 접근 및 제어
    • GET /books
    • GET /books/{bookId}
    • POST /books
    • PUT /books/{bookId}
    • DELETE /books/{booksId}
  • 스프링에서는 요청에 따라 등록되어 있는
    적절한 HttpMessageconverter 를 통해 응답 데이터를 반환한다.

Spring REST DOCs

  • Spring MVC Test와 Asciidoctor 조합을 통해 RESTful 서비스에 대한 문서화 지원
  • 작성된 테스트코드에 대한 아스키독 조각 생성
  • 개발자가 아스키독 조각을 모아 아스키독 문서를 작성한다.
  • 코드에 침투적이지 않은 노력에 따라 고품질의 코드가 될 수 있다.


애플리케이션 작동 정의

@Profile 어노테이션

  • 스프링에서 제공하는 프로파일 에너테이션
  • 컴포넌트를 활성화할 실행환경의 정의
  • 스프링 부트는 하나의 패키징된 배포본을 가지고 다양한 실행환경에서 이용할 수 있도록
    외부 구성을 통해 애플리케이션 속성을 정의할 수 있으며,
    이런 실행환경을 명시적으로 선언하는 애너테이션이 @Profile 이다.
  • @Profile("dev"), @Profile("beta"), @Profile("prod")
  • @ActiveProfile("{profile}")

@Profile - TYPE

@Profile("local")
@Configuration
public class LocalApiConfig {
  @Autowired
  private RestTemplateBuilder restTemplateBuilder;
  
  @Bean
  public RestTemplate restTemplate() {
 	 return restTemplateBuilder.build();
  }
}

@Profile - Method

@Configuration
public class LocalApiConfig {
  @Autowired
  private RestTemplateBuilder restTemplateBuilder;
  @Profile("local")
  @Bean
  public RestTemplate restTemplate() {
  	return restTemplateBuilder.build();
  }
  @Profile("!local")
  @Bean
  public RestTemplate restTemplate() {
  	return restTemplateBuilder.rootUri("http://test.honeymon.io")
  		.build();
  }
}

@Profile - application-{profile}.yml

application-datasource.yml = @Profile("datasource")
application-api.yml = @Profile("api")
application.yml

애플리케이션 속성 정의

  1. 테스트 속성 정의
  2. 실행인자 지정
  3. 운영체제 환경변수 지정
  4. 속성파일 지정 (application.yml OR application.properties)
    @EnableConfigurationProperties
    @ConfigurationProperties
  5. 프로그래밍적 코드 구현

'Back-end > Spring Boot' 카테고리의 다른 글

스프링 부트 웹 서비스 개발  (0) 2021.07.14
스프링 부트 소개  (0) 2021.07.09
스프링 부트 - 배포 및 관리  (0) 2021.06.16
스프링 부트 - 코딩  (0) 2021.06.15
스프링 부트 - 빌드  (0) 2021.06.15

+ Recent posts