Back-end/JAVA,Spring

[Spring Boot] 스프링 부트 MVC 기본 환경설정

cheersHena 2019. 3. 17. 00:49
반응형

스프링 부트  MVC 기본 환경설정

Project 소스구성

메인클래스: DemoApplication.java

프로퍼티파일: application.properties

환경설정파일: pom.xml

>스프링 부트 기반으로 프로젝트 생성시 기존의 전통적인 웹어플리케이션 방식에서 필수로 관리 되어야 하는 톰캣설정 및 web.xml파일 등은 스프링 부트의 내부모듈에 의해서 구동시 자동설정 한다.

 

어플리케이션 실행 

*프로젝트 생성시 application.properties 파일이 자동생성되며 빈 파일로 생성된다.

사용자가원하는 DB 드라이버 라이브러리설치와 jdbc설정 필요.

*당장 결정이 안된경우 메인클래스에 Auto Configuration 작업중 DataSource설정 부분을 제외 시킬 수 있다.

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

스프링 부트 메인 클래스

@SpringBootApplication // (= @Configuration + @EnableAutoConfiguration + @ComponetScan)

@SpringBootApplication // (= @Configuration + @EnableAutoConfiguration + @ComponetScan)

 public static void main(String[] args) {
  SpringApplication.run(SpringbootRestDemoApplication.class, args);
 }

Spring Boot 개발 시 항상 메인 클래스에 @Configuration, @EnableAutoConfiguration , @ComponetScan을 어노테이트한다. 

이 어노테이션들은 자주 함께 사용된다. Spring Boot는 편의를 위해 @SpringBootApplication을 제공한다. 

@SpringBootApplication 어노테이션은 @Configuration, @EnableAutoConfiguration,@ComponentScan을 디폴트 속성으로 함께 사용하는 것과 같다.

 

SpringBoot Web Application 설정

SpringBoot는 프로젝트 생성시 Web 라이브러리를 추가한 경우, 정적인 웹 리소스들은 src > main > resources> static 이하에서 관리 되도록 설정된다. 즉, html, css, js, image등의 정적 컨텐츠는 static폴더 아래 위치시킨다.

*프로젝트 생성시 Web라이브러리 추가 안한경우 pom.xml에서 직접 추가해준다.

<dependency>
 <groupid>org.springframework.boot</groupid>
 <artifactid>spring-boot-starter-web</artifactid>
</dependency>


JSP 설정

1) Application.properties 설정 (src>resources>)

server.port=8888 #기본포트외의 다른 포트를 사용하고 싶으면 별도의 포트를 지정하자.
 
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

톰캣기반 자바 웹어플리케이션에서는 보안상 jsp 위치를 URL로 직접접근할 수 없는 WEB-INF폴더 아래 위치시킨다. 

이 설정들은 스프링부터가 AutoConfiguration을 통해 이미 자동설정한 속성값들을 위의 값으로 오버라이드 하는 개념이다. 

설정 후 웹어플리케이션 구동하면 스프링 부트는 Web킷(추가해준 의존성 라이브러리)에 포함되어있는 라이브러리들 중   MVC관련 라이브러리들을 AutoConfiguration을 통해 기본설정 값으로 셋팅하면서 올라오게 된다.

스프링 부트 메인 어플리케이션에 필수로 존재하는 @SpringBootApplication이 이 역할을 담당한다.

 

스프링부트의 핵심 - AutoConfiguration

//Main class
@SpringBootApplication // (= @Configuration + @EnableAutoConfiguration + @ComponetScan)
 public static void main(String[] args) {
  SpringApplication.run(SpringbootRestDemoApplication.class, args);
}

스프링 부트의 메인어플리케이션 클래스는 @SpringBootApplication 클래스어노테이션을 필수로 가진다.

이 어노테이션은 실제 3개의 어노테이션으로 구성되어 있고 그중하나가 @EnableAutoConfiguration 이다.

 

@SpringBootApplication을 따라가서 Class파일 코드를 살펴보자.

@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 {
    @AliasFor(
        annotation = EnableAutoConfiguration.class
   )
    Class<?>[] exclude() default {};
​
    @AliasFor(
        annotation = EnableAutoConfiguration.class
   )
    String[] excludeName() default {};
​
    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
   )
    String[] scanBasePackages() default {};
​
    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
   )
    Class<?>[] scanBasePackageClasses() default {};
}


상단 클래스 어노테이션을 보면 3개의 어노테이션으로 구성된것을 확인할 수 있다.

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

기본 Java 또는 Spring 기반의 개발환경을 드라마틱한 수준으로 간소화 시킨다는 점에서 스프링 부트의 핵심은 @EnableAutoConfiguration 이라고 할 수 있다. 

스프링 부트 Starter 킷 중 Web 관련 클래스중 WebMvcAutoConfiguration 클래스 코드 일부를 살펴보자.

// WebMvcAutoConfiguration.class의 일부
​
@Configuration
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
    public static final String DEFAULT_PREFIX = "";
    public static final String DEFAULT_SUFFIX = "";
    private static final String[] SERVLET_LOCATIONS = new String[]{"/"};
​
    public WebMvcAutoConfiguration() {
   }
​
    @Bean
    @ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
    public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
        return new OrderedHiddenHttpMethodFilter();
   }
​
    @Bean
    @ConditionalOnMissingBean({HttpPutFormContentFilter.class})
    @ConditionalOnProperty(
        prefix = "spring.mvc.formcontent.putfilter",
        name = {"enabled"},
        matchIfMissing = true
   )
    public OrderedHttpPutFormContentFilter httpPutFormContentFilter() {
        return new OrderedHttpPutFormContentFilter();
   }
​
    static class OptionalPathExtensionContentNegotiationStrategy implements ContentNegotiationStrategy {
        private static final String SKIP_ATTRIBUTE = PathExtensionContentNegotiationStrategy.class.getName() + ".SKIP";
        private final ContentNegotiationStrategy delegate;
​
        OptionalPathExtensionContentNegotiationStrategy(ContentNegotiationStrategy delegate) {
            this.delegate = delegate;
       }
​
        public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException {
            Object skip = webRequest.getAttribute(SKIP_ATTRIBUTE, 0);
            return skip != null && Boolean.parseBoolean(skip.toString()) ? MEDIA_TYPE_ALL_LIST : this.delegate.resolveMediaTypes(webRequest);
       }
   }

 

// WebMvcProperties.class의 일부
package org.springframework.boot.autoconfigure.web.servlet;

@ConfigurationProperties(
    prefix = "spring.mvc"
)
public class WebMvcProperties {
    private Format messageCodesResolverFormat;
    private Locale locale;
    private WebMvcProperties.LocaleResolver localeResolver;
    private String dateFormat;
    private boolean dispatchTraceRequest;
    private boolean dispatchOptionsRequest;
    private boolean ignoreDefaultModelOnRedirect;
    private boolean throwExceptionIfNoHandlerFound;
    private boolean logResolvedException;
    private String staticPathPattern;
    private final WebMvcProperties.Async async;
    private final WebMvcProperties.Servlet servlet;
    private final WebMvcProperties.View view;
    private final WebMvcProperties.Contentnegotiation contentnegotiation;
    private final WebMvcProperties.Pathmatch pathmatch;
​
    public WebMvcProperties() {
        this.localeResolver = WebMvcProperties.LocaleResolver.ACCEPT_HEADER;
        this.dispatchTraceRequest = false;
        this.dispatchOptionsRequest = true;
        this.ignoreDefaultModelOnRedirect = true;
        this.throwExceptionIfNoHandlerFound = false;
        this.logResolvedException = false;
        this.staticPathPattern = "/**";
        this.async = new WebMvcProperties.Async();
        this.servlet = new WebMvcProperties.Servlet();
        this.view = new WebMvcProperties.View();
        this.contentnegotiation = new WebMvcProperties.Contentnegotiation();
        this.pathmatch = new WebMvcProperties.Pathmatch();
   }

이 두개의 클래스를 통해 스프링 부트는 Spring MVC환경에 필요한 속성값들을 AutoConfiguration 통해 지동설정하게 된다.

위의 Application.properties파일에서 Spring.mvc. 까지 프로퍼티를 입력하게 되면 자동완성기능을 통해 에디터에 표시되는 속성들은 모두 WebMvcProperties.class에 정의된 속성들을 보여주는 것이고, 새롭게 정의하는 값으로 오버라이딩 되는 것이다.

우리는 위에서 두가지 속성 : spring.mvc.view.prefix 와 suffix을 새롭에 정의하였다. 

나머지 mvc 관련 속성들은 이 클래스의 기본설정 값으로 적용된다. 

기존에는 ViewResolver를 설정하기 위해 application-context.xml  이 servlet-context.xml 에 추가하거나, Java Config기반의 환경일 경우 @Configuration 클래스 _ WebMvcConfig 등의 클래스에 ViewResolver설정을 해줘야 했었다.

스프링 부트에서는  WebMvc / JDBC / JPA/ LOGGING 등 Spring기반 웹어플리케이션 구동에 필요한 대부분 설정들은 @EnableAutoConfiguration에 의해 자동설정되고 외부로는 드러나지 않는다. 필요속성값만 오버라이딩하여 사용하면 된다.

 

MVC기반 요청 및 응답 

스프링부트는 컴포넌트 스캔시 기본적으로 메인클래스가 있는 위치를 기준으로 컴포넌트 스캔을 한다.

만약 AutoScan되어야 하는 컴포넌트 클래스들 (@Controller, @Service, @Repository,@Component .. ) 위치가 메인 클래스 패키지보다 상위이거나 다른 패키지에 존재하는 경우 스캔이 되지 않는다. 다른 경우에는 임의의 패키지스캔이 되도록 지정할 수 있다. 

@ComponentScan(basePackages = "지정할 베이스 패키지") 
ex)  (basePackages= {"com.example.*"})

 @SpringBootApplication

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@ComponentScan(basePackages = {"com.example.*"})
public class SpringbootRestDemoApplication {
   public static void main(String[] args) {
       SpringApplication.run(SpringbootRestDemoApplication.class, args);
  }
}

MVC설정이 제대로 동작하는지 확인하기 위해서 컨트롤러클래스를 간단히 만들어보자.

@Controller
public class HomeController {

 	@RequestMapping(value="/home")
	 public String home() {
 	 	return "home";
	}
}

스프링 어플리케이션 구동 후 브라우저에 해당 URL (localhost:8080/home) 로 접속해보자.

home.jsp가 호출되어 띄워지면 성공! 

지금까지 설정으로 MVC기반 웹어플리케이션을 개발할 수 있는 아주 기본적인 환경설정이 완료된 것이다.

 

 

반응형