환경 구성
개발 툴 : STS 4 -> Spring boot 개발을 위한 최적화 툴이라고 생각함. Intellij CE(무료버전)으로 개발하다 Web과 Spring 그리고 JSP에 대한 기능 미비로 대체함
빌드도구 : Gradle -> Maven Repository도 지원하면서 빠름, Maven에 비해 간결한 설정
프레임워크 : Spring Boot -> Spring 레거시보다 빠른 프로젝트 시작 가능이 최대의 장점이라고 생각한다. 그리고 확장성 부분도 부트가 나온지 꽤 됐기 때문에.. 레거시보단 못하겠지만 그래도 훌륭하지 않을까. 귀찮음을 해결한 대가라고 생각하자.
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".
- Spring Boot 공식 사이트
의존라이브러리(build.gradle)
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'com.h2database:h2'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
ORM : Spring JPA를 도입하려다 Spring JDBC가 매력있어 보여 대체(https://spring.io/blog/2018/09/17/introducing-spring-data-jdbc, https://brunch.co.kr/@springboot/105)
템플릿엔진 : JSTL 태그라이브러리를 사용한 JSP로 View를 구현하려다 템플릿 엔진을 사용해보고싶어 Thymeleaf 추가
In-MemoryDB : 테스트 환경을 위한 H2(Hsql의 후속이라고 생각되고 웹 콘솔이 매력적)
취향차이?
XXXXXXXApplication.java 이름을 Application.java로 변경 (이름이 너무 길어서)
Java config 작업 전에...
- Spring mvc의 annotation-driven은 필요없다. 이유는 @SpringBootApplication을 명시하니까.
(https://stackoverflow.com/questions/51008382/why-spring-boot-application-doesnt-require-enablewebmvc ,https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-using-springbootapplication-annotation) - 내장 톰캣을 이용하고 싶지 않으면 Application 클래스에 SpringBootServletInitializer를 상속받아 configure를 오버라이드하여 작성하자(참조), STS를 이용한 프로젝트 생성시 배포 방식을 War로 설정하면 자동으로 생성된다.
프로젝트 구조
기본 구성된 프로젝트 구조, 위의 구조를 완성시켜 나가보자
AppConfig 설정
JdbcTemplate 추가 및 Thymeleaf 설정 추가(참고 : Thymeleaf tutorial)
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Autowired
DataSource dataSource;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**");
}
@Bean
public JdbcTemplate getJdbcTemplate() {
return new JdbcTemplate(dataSource);
}
@Bean
public SpringResourceTemplateResolver templateResolver(){
// SpringResourceTemplateResolver automatically integrates with Spring's own
// resource resolution infrastructure, which is highly recommended.
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setPrefix("classpath:templates/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("UTF-8");
// HTML is the default value, added here for the sake of clarity.
templateResolver.setTemplateMode(TemplateMode.HTML);
// Template cache is true by default. Set to false if you want
// templates to be automatically updated when modified.
templateResolver.setCacheable(true);
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine(){
// SpringTemplateEngine automatically applies SpringStandardDialect and
// enables Spring's own MessageSource message resolution mechanisms.
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
// Enabling the SpringEL compiler with Spring 4.2.4 or newer can
// speed up execution in most scenarios, but might be incompatible
// with specific cases when expressions in one template are reused
// across different data types, so this flag is "false" by default
// for safer backwards compatibility.
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
@Bean
public ThymeleafViewResolver viewResolver(){
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
// NOTE 'order' and 'viewNames' are optional
viewResolver.setOrder(1);
viewResolver.setViewNames(new String[] {".html", ".xhtml"});
return viewResolver;
}
}
Model 생성
간단하게 테스트용으로 작성..
public class TestVO {
private String text1;
private String text2;
private String text3;
public TestVO(String text1, String text2, String text3) {
super();
this.text1 = text1;
this.text2 = text2;
this.text3 = text3;
}
public String getText1() {
return text1;
}
public void setText1(String text1) {
this.text1 = text1;
}
public String getText2() {
return text2;
}
public void setText2(String text2) {
this.text2 = text2;
}
public String getText3() {
return text3;
}
public void setText3(String text3) {
this.text3 = text3;
}
@Override
public String toString() {
return "TestVO [text1=" + text1 + ", text2=" + text2 + ", text3=" + text3 + "]";
}
}
Controller 생성
@Controller
public class AppController {
@RequestMapping(value="/")
public String test(Model model) {
TestVO testVO = new TestVO("테스트", "안녕", "반가워");
model.addAttribute("testVO", testVO);
return "test";
}
}
View 생성
Model이 구현되는 템플릿엔진 적용한 HTML파일
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Hello Test Page</h1>
<span th:text="${testVO.text1}"></span><br/>
<span th:text="${testVO.text2}"></span><br/>
<span th:text="${testVO.text3}"></span><br/>
</body>
</html>
결과
'Spring' 카테고리의 다른 글
Spring Jpa - Query DSL + Gradle 6 설정 (3) | 2020.09.21 |
---|---|
Spring Jpa - Paging api 처리하기 (0) | 2020.09.18 |
Spring Data Jpa Auditing (0) | 2020.07.29 |
ApplicationContext와 Singleton (0) | 2020.07.29 |
Spring Security + Rest (0) | 2020.02.19 |