Spring Boot Devtools
Devtools는 Spring Boot에서 제공하는 개발 편의를 위한 모듈이며, 개발 편의를 위해 제공되는 기능은 크게 5가지 입니다.
- Property Defaults
- Automatic Restart
- Live Reload
- Globlas Settings
- Remote Applications
Property Defaults
스프링 부트에 지원하는 여러 라이브러리(ex: thymeleaf Template)의 경우 기본적으로 캐싱 기능을 제공하지만, 개발 과정에서는 개발된 내용이 바로 적용되지 않아 비효율적일 수 있습니다. spring-boot-devtools는 기본적으로 이러한 캐싱 옵션을 비활성화함으로써 개발의 편의성을 높여줍니다.
이렇게 제공되는 기본 속성들의 값은 다음과 같습니다.
번호 | 기본 속성 값 |
1 | devToolsProperties.put("spring.thymeleaf.cache", "false"); |
2 | devToolsProperties.put("spring.freemarker.cache", "false"); |
3 | devToolsProperties.put("spring.groovy.template.cache", "false"); |
4 | devToolsProperties.put("spring.mustache.cache", "false"); |
5 | devToolsProperties.put("server.session.persistent", "true"); |
6 | devToolsProperties.put("spring.h2.console.enabled", "true"); |
7 | devToolsProperties.put("spring.resources.cache-period", "0"); |
8 | devToolsProperties.put("spring.resources.chain.cache", "false"); |
9 | devToolsProperties.put("spring.template.provider.cache", "false"); |
10 | devToolsProperties.put("spring.mvc.log-resolved-exception", "true"); |
11 | devToolsProperties.put("server.jsp-servlet.init-parameters.development", "true"); |
12 | devToolsProperties.put("spring.reactor.stacktrace-mode.enabled", "true"); |
Automatic Restart
개발을 하다보면 클래스 내의 필드 하나를 고치더라도 재시작해야하는 번거로움이 생기게 됩니다. spring-boot-devtools에서는 파일의 변경을 감지하고 자동으로 재시작을 해줌으로써 개발의 편의성을 높여줍니다.
※ 재시작 방법은 IDE에 따라 달라지는데, Eclipse(STS)는 Classpath에 수정된 파일이 저장된 경우 재시작하고 Intellij는 빌드된 경우 재시작됩니다.
참고로 설정을 통해 특정 폴더의 변경 사항은 탐지하지 않거나 특정 폴더만 탐지하도록 변경할 수 있습니다.
IntelliJ 설정 방법
1. build.gradle.kts에서 devtools을 추가함
dependencies {
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
2. Settings > Advanced Settings > Allow auto-make to start even if developed applications is currently running 체크
3. Settings > Build, Execution, Deployment > Complier > Build project automatically 체크
Live Reload
spring-boot-devtools에서는 내부 리소스가 변경될 때마다 자동으로 브라우저를 리플레시 해주는 Live Reload Server를 지원합니다. 크롬 확장 플러그인을 다운로드 받고 Enable 함으로써 사용할수 있습니다.
application.properties
spring.devtools.livereload.enabled=true
spring.thymeleaf.prefix=file:src/main/resources/templates/
spring.resources.static-locations=file:src/main/resources/static/
Live Reload Server를 실행하지 않으려면 spring.devtools.livereload.enabled 속성을 False로 설정하면 됩니다.
Global Settings
spring-boot-devtools에서는 전역 설정을 지원함으로써 해당 서버에 존재하는 모든 Spring Boot의 애플리케이션에 적용시킬 수 있습니다.
Remote Applications
spring-boot-devtools에서는 애플리케이션을 원격에서 실행하기 위한 여러가지 기능들을 지원하고 있습니다. 다만 해당 기능의 경우 보안적 위험이 있을 수 있기 때문에 적절히 사용을 해야합니다.
Spring Web
Spring MVC를 이용하여 웹 애플리케이션(RESTful 포함)을 구축할 수 있는 기능을 가지고 있으며, Apache Tomcat을 내장 컨테이너로 사용하고 있습니다.
Thymeleaf
Thymeleaf는 View Template Engine으로 Controller에서 전달받은 데이터를 이용하여 동적인 웹 페이지를 만들 수 있습니다. 또한, HTML 태그를 기반으로 하며 th: 속성을 이용하여 동적인 View를 생성할 수 있습니다.
<!-- 기본 사용 방식 -->
<p th:text="${test}"></p>
<!-- if문과 if else문 -->
<p th:if="${a>5}">a가 크다</p>
<p th:unless="${a>5}">a는 5보다 작다</p>
<!-- 반복문 -->
<th:block th:each="test: ${list}>
<p th:text="${test[0]}"></p>
<p th:text="${test[0]}"></p>
</th:block>
Spring Data JPA
JPA (Java Persistence API)
자바 애플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스이며, 특정 기능을 하는 라이브러리가 아닙니다.
※ 실제로 Datababse와 소통하는 것은 JDBC(Java Database Connectivity)
Hibernate
Hibernate는 JPA라는 인터페이스를 구현한 구현체라고 볼 수 있습니다. JPA와 Hibernate는 마치 Java의 interface와 해당 interface를 구현한 Class와 같은 관계입니다.
Spring Data JPA
Spring Data JPA는 Spring에서 제공하는 모듈 중 하나로 개발자가 JPA를 더 쉽고 편리하게 사용할 수 있도록 도와줍니다. 이는 JPA를 한 단계 추상화시킨 Repository Interface를 제공함으로써 이루어지며, 사용자가 정해진 규칙대로 메서드 명을 입력할 경우 Spring에서 입력된 메서드 명에 맞게 적합한 쿼리를 구성하여 구현체를 Bean에 등록합니다.
Spring을 이용하여 개발할 경우 JPA의 핵심이 되는 EntityManager를 직접적으로 다룰 일이 거의 없는데 이는 대부분 Repository라는 인터페이스를 사용하기 때문입니다. Repository의 기본 구현체인 SimpleJpaRepository의 코드를 보면 알 수 있듯이 내부적으로 EntityManager를 사용하고 있습니다.
package org.springframework.data.jpa.repository.support;
import ...
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {
private final EntityManager em;
public Optional<T> findById(ID id) {
Assert.notNull(id, ID_MUST_NOT_BE_NULL);
Class<T> domainType = getDomainClass();
if (metadata == null) {
return Optional.ofNullable(em.find(domainType, id));
}
LockModeType type = metadata.getLockModeType();
Map<String, Object> hints = getQueryHints().withFetchGraphs(em).asMap();
return Optional.ofNullable(type == null ? em.find(domainType, id, hints) : em.find(domainType, id, type, hints));
}
// Other methods...
}
Method 명 규칙 (출처)
Keyword | Sample | JPQL snippet |
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstname,findByFirstnameIs,findByFirstnameEquals | … where x.firstname = 1? |
Between | findByStartDateBetween | … where x.startDate between 1? and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age ⇐ ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection<Age> ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection<Age> age) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
H2 Database
H2 Database(이하 H2DB)는 Java 기반의 오픈소스 RDBMS입니다. 주로 인 메모리 데이터베이스(휘발성 데이터베이스)로 사용되며 개발 및 테스트 시 사용됩니다. 컴퓨터가 종료되면 사라지는 휘발성 데이터베이스가 아닌 영구적으로 데이터가 남아있는 디스크에 저장하는 방식으로도 사용할 수 있습니다.
'Study > WEB' 카테고리의 다른 글
[Spring Boot With Kotlin] RESTFul API, JSON 데이터 처리하기 (0) | 2022.07.24 |
---|---|
[Spring Boot With Kotlin] 오류 별 해결 방안 정리 (0) | 2022.07.24 |
[Spring Boot With Kotlin] Web Server Tutorial (Feat. Intellij) (0) | 2022.07.23 |
JSP(Java Server page)와 Java Servlet (0) | 2022.07.13 |
PHP에서 TCPDF로 HTML 화면을 PDF로 변환하기 (0) | 2022.05.18 |
댓글