[Spring] 스프링 입문 복습

bin1225·2021년 10월 25일
0

Spring

목록 보기
11/15
post-thumbnail

Maven,Gradle

프로젝트를 진행하면 다양한 라이브러리를 이용하게 되는데, 이 라이브러리를 가져오고 관리해주는 툴이다. 최근에는 Gradle을 주로 이용하는 추세이다.

Spring Boot Version

뒤에 괄호가 있는 버전은 정식 버전이 아니다.

build.gradle

build.gradle 파일을 통해 프로젝트를 생성한다.
plugins {
	id 'org.springframework.boot' version '2.3.1.RELEASE'
	id 'io.spring.dependency-management' version '1.0.9.RELEASE'
	id 'java'
}
group = 'hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
	mavenCentral()
}	//라이브러리를 어디서 가져오는지
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation('org.springframework.boot:spring-boot-starter-test') {
	exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
	useJUnitPlatform()
}
  • test

    자동으로 테스트 관련 라이브러리 ( Junit5 )를 가져온다.

  • dependencies

    dependencies 에 있는 것들이 해당 프로젝트가 쓰는 라이브러리들이며, gradle이 이 라이브러리를 사용하는데 필요한 하위 라이브러리들을 모두 자동으로 가져와서 관리한다.

spring-boot-starter-web
- spring-boot-starter-tomcat: 톰캣 (웹서버)
- spring-webmvc: 스프링 웹 MVC
spring-boot-starter-thymeleaf: 타임리프 템플릿 엔진(View)
spring-boot-starter(공통): 스프링 부트 + 스프링 코어 + 로깅
spring-boot
- spring-core
spring-boot-starter-logging
- logback, slf4j

스프링 웹 개발 기초

정적 컨텐츠


스프링 부트에는 톰켓 서버가 내장돼있어서 자체적으로 서버를 띄운다.
웹 브라우저에서 서버로 요청이 들어오면 해당 url에 해당하는 컨트롤러를 찾는데, 이 컨트롤러가 존재하지 않을 시에 그 이름을 가진 정적 컨텐츠를 찾아서 응답한다.

MVC


요청 url을 매핑하는 컨트롤러에 있는 로직을 수행한다. 컨트롤러에서는 model에 데이터를 담아서 view에 반환하면 템플릿엔진이 view 를 수정해서 응답한다. 컨트롤러에서 String으로 반환하면 그 이름에 맞는 view를 자동으로 찾아서 수정한다.

API


view를 거치지 않고 데이터를 직접 반환하는 방식이다. 서버와서버간의 요청 응답에도 사용된다.
컨트롤러에 @ResponseBody어노테이션을 붙이면 API응답 방식으로 응답하게 되고 String을 반환하면 해당 문자열을 그대로 http body에 전달, 객체를 반환하면 그 객체를 클라이언트 요청 형식( HTTP Accept 헤더 )에 따라 변환해서 전달한다.( 기본은 Jason형식 )

예제의 경우 더 복잡한 예제를 이미 spring-mvc-1편에서 다뤘기 때문에 내용을 전부 다 정리하지는 않겠다.

일반적인 웹 애플리케이션 계층 구조

  • 컨트롤러: 웹 MVC의 컨트롤러 역할
  • 서비스: 핵심 비즈니스 로직 구현
  • 리포지토리: 데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리
  • 도메인: 비즈니스 도메인 객체, 예) 회원, 주문, 쿠폰 등등 주로 데이터베이스에 저장하고 관리됨

특이사항

이 예제의 경우 repository가 아직 선정이 안됐다는 가정하에 진행했기 때문에 repository를 인터페이스로 먼저 설계하고 그 구현체를 설계했다.

이렇게 설계했을 때 장점은 인터페이스에 맞게 구현돼있기 때문에 나중에 교체시에 이 형식에 맞게 설계만 하면 다른 코드를 많이 수정하지 않고 repository를 교체할 수 있어 변경에 용이하다.

Repository 구현

  • Repository 인터페이스
public interface MemberRepository {
 Member save(Member member);
 Optional<Member> findById(Long id);
 Optional<Member> findByName(String name);
 List<Member> findAll();
}

이렇게 인터페이스의 각 요소는
반환타입 함수명(매개변수) 의 구조로 정의한다.

public class MemoryMemberRepository implements MemberRepository {

이 인터페이스를 상속하는 구현체는 implements 를 통해 상속한다.

  • Optional
    java8 이후로 나온 기능으로 값을 한 번 감싸서 nullpointException을 방지한다.

test case

class MemoryMemberRepositoryTest {
	MemoryMemberRepository repository = new MemoryMemberRepository();
 @AfterEach
 public void afterEach() {
 	repository.clearStore();
 }
 @Test
 public void save() {
 	//given
 	Member member = new Member();
	 member.setName("spring");
 	//when
	 repository.save(member);
    	//then
 	Member result = repository.findById(member.getId()).get();
 	assertThat(result).isEqualTo(member);
 	}
 }
  • @AfterEach
    이 애노테이션이 붙은 메소드는 각각의 테스트 실행이 종료될 때마다 실행된다.
    ( 반대는 @BeforeEach )
    테스트 종료시마다 repository를 비워줌으로써 오류를 방지한다.

    스프링 빈과 의존관계

    컴포넌트 스캔과 자동 의존관계 설정

    스프링 실행시에 @Component 애노테이션이 있으면 자동으로 bean으로 등록된다.
    @Service, @Repository, @Controller 는 @Component 애노테이션을 내포한다.

  • 생성자 주입 예시

 @Service
public class MemberService {
 	private final MemberRepository memberRepository;
 	
    @Autowired
	 public MemberService(MemberRepository memberRepository) {
 		this.memberRepository = memberRepository;
 	}
}

이렇게 빈으로 등록된 객체들은 @Autowired를 통해 의존관계 자동 주입을 할 수 있고 그 대상이 되기도 한다.

자바 코드로 직접 스프링 빈 등록하기

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

@Configuration, @Bean 애노테이션을 통해 직접 의존관계를 주입하는 코드이다.
@Configuration 애노테이션이 붙어 있으면 스프링 실행시에 스프링이 해당 클래스를 확인하고 각 요소들을 Bean으로 등록한다.

* 참고: 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다.
그리고 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.

회원 관리 예제 - 웹 MVC 개발

  • SPRING-MVC-1편 에서 다뤘기 때문에 생략

스프링 DB 접근 기술

  • JPA 기본편에서 다뤘기 때문에 생략

AOP

AOP가 필요한 상황

AOP: Aspect Oriented Programming

공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern) 분리
ex) 모든 메소드의 호출 시간 측정
시간 측정은 공통 관심 사항이지만 핵심 관심 사항은 아니다.

0개의 댓글