Spring 부트

23-02-10) 스프링 부트 2강 - 스프링부트 기본설정, 뷰, bean 수동설정, TTD ( Test driven development) , lombok과 builder 패턴

JadeStone 2023. 2. 10. 18:57

2강

1. JPA를 이용한 Database 자동연결

2. Thymeleaf 뷰 템플릿 vs JSP뷰 템플릿

3. 스프링부트에서 bean설정 파일

4. TTD란

5. Lombok과 Builder패턴

 

<프로젝트 생성>

 

#프로젝트 생성

*스프링 부트의 버전도 꼭 설정해줘야 함.

 

# bulid.gradle 확인

* gradle 에 모듈들을 더 추가하고자 한다면 

  maven repository 에서  gradle(short) 부분의 내용을 복사해서 가져오면 됨.

 이 때 마지막 부분에 버젼을 따로 기재 안 한다면 

 프로젝트의 스프링 부트의 버젼을 저절로 맞춰줌.

 ex)

# 데이터베이스 연결

* Application.properties ( 설정 파일)

 

* jpa 모듈

로그 보여주는 것 (데이터베이스가 연결됬는지 로그를 보려고 다운받아봤음).

 

gradle 에 모듈 추가하고 ( 버전은 지웠음)

 

gradle 리프레쉬

 

하지만 jpa 가 없어도 

application.properies 에 

아래 처럼 있으면 데이터 베이스는 자동으로 연결된 것.

### 데이터베이스 연결, 커넥션 풀 자동연결 ###
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spring?serverTimezone=Asia/Seoul
spring.datasource.username=spring
spring.datasource.password=spring

# 스프링 부트에 뷰를 붙이고 싶을 때 1. jsp

1. 그레이들 파일

* jsp 해석기

*jstl

2. 리졸버 뷰 선언

application.properties 에 아래와 같이 추가

##jsp를 뷰로 사용하려면 리졸버 뷰 선언
##경로가 아래와 같은 이유는 webapp 폴더부터 경로가 시작되기 때문
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

3. 프로젝트의 구조를 spring 이랑 똑같이 만든다.

* sts4에서는 jsp 파일을 만들어주는 플러그인이 없어서

 html 파일을 만들고 확장자를 jsp 로 바꿔주고 

 jsp 선언부분을 가져와서 위에 붙여줬음. 

 

sts 3 는 jsp 플러그인이 있음

sts 4 는 jsp 플러그인이 없음 ( eclipse marketplace 에서 모듈 다운 받으면 가능하긴함)

 

jsp 를 사용하고자 한다면 sts3 로 작업하기.

 

# 뷰 선택 2. Thymeleaf템플릿

 

1. 그레이들파일

*build.gradle 파일

- 버전을 지웠음. ( 뒤에있는 버전을 지우면 자동으로 스트링 부트의 버전을 따라감)

 

	//타임리프 뷰를 사용하려면
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

2. templet 패키지 이하에  html 파일 생성

 

 

-----------------------  뷰의 선택은 본인의 선택임 원하는걸 찾아서 붙이면 됨.  -----------------------

 

<스프링 부트에서의 개별적인 bean 설정>

* 버젼별로 빈설정이 들어가는게 다름.

* 스프링 부트에서는 자바파일로 스프링 설정파일을 만듦.

 

* 개별적으로 스프링 빈을 등록

-빈으로 만들 클래스 파일

package com.simple.basic.config;

public class TestBean {
	
	public void hello() {
		System.out.println("hello");
	}

}

 

-WebConfi.java (개별적인 스프링 빈 설정 파일)

위에 파일을 두번째 메서드에서 빈으로 등록함.

package com.simple.basic.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration //개별적인 스프링 빈 설정 파일
public class WebConfig implements WebMvcConfigurer{

	@Bean  //해당 메서드 실행하게됨 
	public void test() {
		System.out.println("실행됨");
		
	}
	@Bean //해당 메서드 실행하게됨
	public TestBean testBean() {
		System.out.println("테스트 빈 실행됨2");
		return new TestBean(); //return에 실려있는 클래스가 빈으로 등록이 되는것.
	}
	
}

 

 

* applicationContext 는 스프링 컨테이너임. 안에는 생성된 빈들이 있음.

* @Value 어노테이션을 붙이면 application.properties 파일의 변수 값들을 참조해올 수 있음.

 

코드로 확인

package com.simple.basic.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.simple.basic.controller.HomeController;

@Configuration //개별적인 스프링 빈 설정 파일
public class WebConfig implements WebMvcConfigurer{
	
	//빈을 보관하고 있는 장소 (스프링 컨테이너)
	@Autowired
	ApplicationContext applicationContext;
	
	//properties파일에 선언된 변수를 바로 참조
	@Value("${server.port}")
	String port;

	@Bean  //해당 메서드 실행하게됨 
	public void test() {

		TestBean t = applicationContext.getBean(TestBean.class);
		System.out.println(t);
		
		HomeController h = applicationContext.getBean(HomeController.class);
		System.out.println(h);
		
		int c = applicationContext.getBeanDefinitionCount();
		System.out.println("빈의개수:" + c);
		
		System.out.println("properties에 선언된값:" + port);
		
	}
	@Bean //해당 메서드 실행하게됨
	public TestBean testBean() {
		System.out.println("테스트 빈 실행됨2");
		return new TestBean(); //return에 실려있는 클래스가 빈으로 등록이 되는것.
	}
	
}

 

 

 

<TDD 개발과 테스트 코드>

#TDD

*테스트 주도하에 개발을 해 나간다. (방법론일 뿐 현실적으로 이렇게 개발하는데는 한계가 있음)

* 테스트 클래스

package com.simple.basic;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import com.simple.basic.controller.HomeController;

@SpringBootTest //스프링부트 테스트 클래스
public class BootTest {
	
	@Autowired
	HomeController homeController;
	
	@Test
	public void testCode01() {
		System.out.println(homeController.home());
	}

}

 

 

<Bulider 패턴 (디자인 패턴)>

* 클래스 안에 클래스가 있는 것을 내부클래스라고 함.

*빌더패턴

- 스프링 부트에서는 이 패턴을 참 좋아함.

장점 -> 변수가 불변

단점 -> 설계가 어렵다

 

*BuilderVO.java

package com.simple.basic.command;

public class BuilderVO {
	//빌더 패턴의 모형 - 내부 클래스를 생성하고, 외부에서 호출시에 내부클래스에 값을 지정
	//장점 - 객체의 불변성 (값의 변경을 막고, 사용시 가독성이 좋다)
	
	//1. 멤버변수
	private String name;
	private int age;
	
	//4.VO의 생성자
	private BuilderVO(Builder builder) {
		this.name = builder.name;
		this.age = builder.age;
	}
	
	//7. 외부에서 객체생성을 요구하면 내부에 있는 Builder클래스를 반환
	public static Builder builder() {
		return new Builder();
	}
	
	//8. toString 오버라이딩
	@Override
	public String toString() {
		return "Builder [name=" + name + ", age=" + age + "]";
	}
	
	
	//2. 내부클래스 생성 - 클래스 안에 클래스 (이너클래스, 네스티드 클래스로 불리기도 함)
	public static class Builder{
		private String name;
		private int age;
		
		//3. 생성자 제한
		private Builder() {}
	
		//5. 내부 클래스에 setter메서드 생성
		public Builder setName(String name) {
			this.name = name;
			return this;
		}
		
		public Builder setAge(int age) {
			this.age = age;
			return this;
		}
		//6. build 메서드를 생성 - 나자신을 외부클래스에 저장하고 반환
		public BuilderVO build() {
			return new BuilderVO(this);
		}
	}
	

}

 

*빌더패턴 사용

Test.java

package com.simple.basic;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import com.simple.basic.command.BuilderVO;
import com.simple.basic.command.BuilderVO.Builder;
import com.simple.basic.controller.HomeController;

@SpringBootTest //스프링부트 테스트 클래스
public class BootTest {
	
//	@Autowired
//	HomeController homeController;
//	
//	@Test
//	public void testCode01() {
//		System.out.println(homeController.home());
//	}
	
	//빌더패턴 객체의 사용
	@Test
	public void testCode02() {
		
//		Builder xx = BuilderVO.builder();
//		xx = xx.setAge(10);
//		xx = xx.setName("홍길동");
//		BuilderVO vo = xx.build();
//		System.out.println(vo.toString());
		
		BuilderVO vo = BuilderVO.builder().setAge(10)
						   .setName("홍길동")
						   .build();
		System.out.println(vo.toString());
		
	}
	

}

 

* lombok 에서 

@Builder  어노테이션을 사용해주면 자동으로 빌드패턴으로 생성해줌.

package com.simple.basic.command;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data //get, set, toString
@NoArgsConstructor // 기본생성자
@AllArgsConstructor //모든 생성자
@Builder //빌더 패턴
public class BuilderVO2 {
	
	private String name;
	private int age;

}