단의 개발 블로그
프로젝트 생성 및 프로젝트 구조 본문
프로젝트생성
인텔리제이 file - new - project 클릭

왼쪽 Spring initiallizr 클릭 - Name : 프로젝트 명 입력, 나머지는 각자 해당 사항에 맞게 설정

초기 라이브러리는 lombok, dev tools, thymeleaf, spring web으로 설정 후 create 클릭

다음과 같이 폴더와 파일이 만들어진다.

프로젝트 구조
| 폴더 및 파일 | 설명 |
| src/main/java | 애플리케이션 소스 코드가 위치하는 곳 |
| src/test/java | 테스트 코드가 위치하는 곳 |
| src/main/resources | 리소스 파일이 위치하는 곳 |
| .gradle | gradle이 사용하는 폴더, task로 생성된 파일이 저장되며 편집하는 일이 거의 없음 |
| .idea | 인텔리제이 구성 관련 디렉토리 |
| gradle | gradle이 사용하는 폴더로 gradle 설정을 정리한 wrapper 파일이 저장된다 |
| .gitignore | git이 파일이나 폴더를 추적하지 않을 리스트를 저장하고 있는 파일이다. |
| build.gradle | gradle 빌드 설정 파일이다. groovy or kotlin으로 작성되어 있다. |
| gradlew | gradle 명령파일로 POSIX 운영체제에서 사용하는 파일이다. |
| gradle.bat | gradle 명령파일로 WINDOW에서 사용하는 파일이다. |
| setting.gradle | 프로젝트 설정 파일이다. |
Gradle
빌드와 빌드 툴
빌드란 소스코드를 실행 가능한 파일로 만드는 과정을 말한다. Java로 작성된 프로그램은 빌드를 통해 파일명.jar or 파일명.war로 빌드된다. 서버는 해당 파일을 실행시켜 Java 애플리케이션을 실행시킨다.
빌드툴이란 프로그램이 고도화 되면서 여러 가지 라이브러리를 추가하게 되는데, 이때 해당 언어, 해당 프레임워크 버전에 호환되는 라이브러리를 사용하는 것이 중요하다. 이를 편하게 관리하고자 Ant, Maven, Gradle이 등장했다.
Maven
원래 이전에 많이 사용되던 빌드 툴이다. Apache Maven은 자바용 프로젝트 관리 도구다. Ant 보다 편하게 사용되고자 개발되었으며 해당 라이브러리가 작동하는데 필요한 타 라이브러리들까지 관리해 준다. XML를 사용하여 작성한다.
Gradle
현재까지 개발된 여러 빌드 툴의 장점을 모아서 만든 도구이다. Groovy or Kotlin으로 작성 가능해 확장성이 뛰어나다. Maven은 프로젝트가 커질 수록 빌드 스크립트의 내용이 길어지며 가독성이 떨어지는데, Gradle은 적은 양으로 간결하게 작성이 가능하다. Maven은 다른 모듈에서 사용하려면 상속을 받아야 하지만 Gradle은 설정을 주입하는 방식으로 사용하기 때문에 Maven보다 10 ~ 100배 빠른 속도로 빌드가 가능하다.
- build.gradle
// 플러그인 설정
plugins {
// 자바 프로젝트를 위한 기본 플러그인
id 'java'
// Spring boot 애플리케이션을 위한 플러그인, 3.2.5 버전 사용
id 'org.springframework.boot' version '3.2.5'
// 의존성 관리를 자동화 하기 위한 플러그인, 1.1.4 버전 사용
id 'io.spring.dependency-management' version '1.1.4'
}
// 프로젝트 그룹과 버전 설정
// 프로젝트를 식별하고, 버전을 관리
group = 'com.example'
version = '0.0.1-SNAPSHOT'
// 자바 설정
java {
// 소스 호환성을 Java 17로 설정
sourceCompatibility = '17'
}
// gradle 프로젝트의 종속성 관리를 설정
configurations {
// 아래 옵션을 사용하여 구성
// compile : 컴파일 시 필요한 종속성을 정의
// runtime : 실행 시 필요한 종속성을 정의
// testCompile : 테스트를 컴파잃 할 때 필요한 종속성을 정의
// testRuntime : 테스트를 실행할 때 필요한 종속성을 정의
compileOnly {
// extendsFrom : 구성 간의 상속 관계를 정의, 한 구성이 다른 구성으로부터 상속 받을 수 있또록 해줌
// annotationProcessor : 컴파일 시 소스코드를 분석하고 특정 어노테이션이 적용된 요소에 추가적인 작업을 함
// lombok, Dagger, Room 등의 라이브러리에서 많이 사용 됨
extendsFrom annotationProcessor
}
}
// 저장소 설정
repositories {
// Maven 저장소로 설정
mavenCentral()
// 이외에도 jcenter() or maven { url 'https//repo.xxxxxxxx.xxxxxxx ' } 등으로 지정할 수 있음
}
// 프로젝트 의존성 정의
dependencies {
// implementation : 프로젝트 코드에 직접 사용되는 라이브러리
// testImplementation : 테스트 시 필요한 라이브러리
// compileOnly : 컴파일 시에만 필요하고 런타임에는 포함되지 않는 라이브러리
// developmentOnly : 개발 시에만 필요한 라이브러리
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
// Gradle 프로젝트의 작업 단위
// Gradle 실행 시 name('테스크명') 테스크 명으로 실행
tasks.named('test') {
// 테스크가 실행하면서 필요한 작업을 프로그래밍
// 자바 프로그래밍용 단위 테스트 프레임워크 실행
useJUnitPlatform()
}
- setting.gradle
// Gradle 프로젝트의 설정을 정의
// 프로젝트 명 설정
rootProject.name = 'taco'
// 멀티 모듈일 경우
// include '모듈1', '모듈2'...
// 각 모듈에 대한 설정을 개별적으로 정의
// project(':모듈1').projectDir = new File('모듈경로')
스프링 실행과정
자바 애플리케이션이 JAR파일에서 실행되려면 제일 먼저 시작되는 부트스트랩 클래스가 있어야 한다. 해당 애플리케이션이 스프링이라면, 스프링 구성을 위한 최소한의 구성도 해당 부트스트랩 클래스에 포함되어야 한다. 기존에 생성된 애플리케이션 코드는 아래와 같다.
@SpringBootApplication
public class TacoApplication {
public static void main(String[] args) {
SpringApplication.run(TacoApplication.class, args);
}
}
- JAR 파일이 실행되면, main 메소드가 실행된다. main 메서드 내 SpringApplication의 run 함수가 실행되고, 두 개의 매개 변수를 파라미터로 갖는다. 하나는 구성 클래스, 하나는 명령 인자이다. 구성 클래스는 꼭 부트스트랩 클래스와 같아야 하진 않지만 통상적으로 같게 작성한다. 명령행 인자는 스프링 애플리케이션 인자를 전달하여 특별한 옵션으로 실행시킬 때 사용한다.
제일 먼저 @SpringBootApplication 어노테이션이다. 해당 어노테이션을 살펴보면 아래와 같다.
@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 @interface SpringBootApplication {
...
@Target, @Retention, @Documentd, @Inherited는 어노테이션 생성 시 해당 설정에 관련된 부분이고, 아래 3개의 어노테이션이 해당 설정에 관한 부분이다. 코드에 달린 주석은 제거하고 살펴보자.
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
@SpringBootConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
- 현재 클래스를 구성클래스로 지정한다. 애플리케이션에는 반드시 하나의 @SpringBootConfiguration만 포함되어야 한다. 해당 어노테이션에는 proxyBeanMethods가 있는데, 해당 메소드는 @Bean 라이프 사이클 동작을 강제 여부를 지정하는 함수이다. 예를 들어서 사용자가 코드에서 @Bean을 호출할 경우에도 Shared Singleton bean instance를 반환하기 위해서 필요하다. 기본값은 true이며, 외부에서 @Bean 메서드를 호출할 수 있도록 한다.
- 프록시 : 어떤 것을 사용하려고 할 때 직접 사용하는 것이 아닌 중간에 프록시라는 가짜를 두어 해당 프록시가 받아서 실제 사용하려는 어떤 것을 호출하는 방식이다.
@EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
- 스프링 부트 자동-구성을 활성화 한다. 자동 구성 클래스는 일반적으로 classpath 및 정의된 bean에 기반하여 적용된다. 예를 들어 classpath에 tomcat-embeded.jar가 있다면, TomcatServletWebServerFactory로 사용하게 되는데 이 어노테이션에 설정한 자동 구성 설정만으로도 @SpringBootApplication을 사용할 때 컨텍스트의 자동 구성이 자동으로 활성화된다.
- 만약 자동구성을 원하지 않는 경우 exclude를 사용하여 자동구성에서 제외할 수 있다. 접근 권한이 없는 경우는 excludeName을 사용한다.
@ComponentScan
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
boolean useDefaultFilters() default true;
Filter[] includeFilters() default {};
Filter[] excludeFilters() default {};
boolean lazyInit() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({})
@interface Filter {
FilterType type() default FilterType.ANNOTATION;
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String[] pattern() default {};
}
}
- 컴포넌트 검색을 활성화 한다. @Controller, @Component, @Service 등의 어노테이션과 함께 클래스를 선언할 수 있게 해 준다. 스프링 애플리케이션이 컨텍스트에 해당 클래스를 컴포넌트로 등록한다.
스프링 테스트
모든 소프트웨어 개발에는 테스트가 중요하다. (TDD) 스프링 또한 테스트 관련 기능을 제공한다.
@SpringBootTest
class TacoApplicationTests {
@Test
void contextLoads() {
}
}
@SpringBootTest
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(SpringBootTestContextBootstrapper.class)
@ExtendWith(SpringExtension.class)
public @interface SpringBootTest {
@AliasFor("value")
String[] properties() default {};
String[] args() default {};
Class<?>[] classes() default {};
WebEnvironment webEnvironment() default WebEnvironment.MOCK;
UseMainMethod useMainMethod() default UseMainMethod.NEVER;
enum WebEnvironment {
MOCK(false),
RANDOM_PORT(true),
DEFINED_PORT(true),
NONE(false);
private final boolean embedded;
WebEnvironment(boolean embedded) {
this.embedded = embedded;
}
public boolean isEmbedded() {
return this.embedded;
}
}
enum UseMainMethod {
ALWAYS,
NEVER,
WHEN_AVAILABLE;
}
}
- 스프링 부트 기반 테스트를 실행하는 테스트 클래스에 지정하는 어노테이션이다. 일반적인 기능은 다음과 같다.
- 특정 @ContextConfiguration(loader=..)가 정의되지 않은 경우 기본 ContextLoader로 SpringBootContextLoader를 사용한다.
- 중첩 @Configuration이 사용되지 않고 명시적인 클래스가 지정되지 않은 경우 @SpringBootConfiguration을 자동으로 검색한다.
- properties 속성을 사용하여 사용자 정의 환경 프로퍼티를 정의할 수 있다.
- args 속성을 사용하여 애플리케이션 인자를 정의할 수 있다.
- 다양한 웹 환경 모드를 지원하고, 정의되거나 정의되지 않은 무작위 포트에서 웹 서버를 시작하는 기능도 제공한다.
- 실행 중인 서버에 요청하는 테스트일 경우 TestRestTemplate / WebTestClient 빈을 등록하여 사용할 수 있다.
@Test
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@API(status = STABLE, since = "5.0")
@Testable
public @interface Test {
}
- @Test는 메소드가 테스트임을 알려주는 어노테이션이다. 테스트 메소드는 private이거나 static, 반환 값을 가지면 안 된다. 만약에 테스트 실행 중 순서가 보장돼야 한다면, @TestMethodOrder를 사용하여 테스트를 지정한다.
출처
https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=239755024&start=slayer
'Web > Spring' 카테고리의 다른 글
| 데이터 베이스 (0) | 2024.09.04 |
|---|---|
| 사용자 요청 처리하기 (0) | 2024.09.03 |
| 간단한 웹 요청 만들기 (0) | 2024.05.08 |
| 스프링 요청 및 라이브러리 살펴보기 (1) | 2024.05.02 |
| Spring 이란? (0) | 2024.04.18 |