본문 바로가기

프로그래밍/Spring

스프링 Spring Java 설정 환경설정하기(web.xml 삭제)

보통 'Spring Legacy Project'는 XML기반으로 스프링 설정을 하게 되어있는데 요새는 XML과 별개로 JAVA를 이용하는 설정(Java Configuration)이 대세이다. 예전 프로젝트에서는 XML을 기반으로 하여서 프로젝트를 작성하여서 이번 개인 프로젝트에서는 자바 설정을 이용하여 해보기로 하였다. 우선 자바 설정의 장점은 클래스 기반이기 때문에 자동완성이 된다는점, 알아보기 편하다는 점이 있다.

1. web.xml, servlet-context.xml, root-context.xml 파일을 삭제한다. 이 때 servlet-context.xml, root-context.xml은 spring 폴더 내에 있으므로 스프링 폴더를 아예 삭제해버린다.

2. 삭제 후에 pom.xml에 에러 표시가 뜬다. pom.xml에 들어가서 하단부 <plugins>안에 설정을 추가해준다. 그러면 빌드되면서 에러가 해결이 된다. 이 설정은 web.xml이 없다는 설정이다.

<plugin>

        <groupId>org.apache.maven.plugins</groupId>

        <artifactId>maven-war-plugin</artifactId>

        <version>3.2.0</version>

        <configuration>

            <failOnMissingWebXml>false</failOnMissingWebXml>

        </configuration>

    </plugin>

3. 컴파일 관련 버전도 1.8로 수정한다(자바가 1.8) 그리고 프로젝트 우클릭 후 maven>update project를 한다.

<plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-compiler-plugin</artifactId>

                <version>2.5.1</version>

                <configuration>

                    <source>1.8</source>

                    <target>1.8</target>

                    <compilerArgument>-Xlint:all</compilerArgument>

                    <showWarnings>true</showWarnings>

                    <showDeprecation>true</showDeprecation>

                </configuration>

            </plugin>

이제 기본적인 설정은 다 되었다 ! 이제 xml 대신 설정 파일을 직접 작성하면 된다. @Configuration 이라는 어노테이션이 있는데 이것이 해당 클래스의 인스턴스를 이용해서 설정파일을 대신한다.

4. 프로젝트 폴더 내부에 패키지이름.config 폴더를 생성하고 RootConfig 클래스를 작성한다.

5. web.xml을 대신할 WebConfig 클래스 파일도 kr.co.portfolio.config 패키지 내에 만들어준다. 이 클래스는 AbstractAnnotationConfigDispatcherServletInitializer 을 상속받는다. 상속받아서 add method 해주면 대략 이렇게 클래스 내부가 보인다.

package kr.co.portfolio.config;


import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;


public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer{


@Override

protected Class<?>[] getRootConfigClasses() {

// TODO Auto-generated method stub

return null;

}


@Override

protected Class<?>[] getServletConfigClasses() {

// TODO Auto-generated method stub

return null;

}


@Override

protected String[] getServletMappings() {

// TODO Auto-generated method stub

return null;

}


}

3개의 추상 메소드를 오버라이드 하도록 작성되는데 이 때 getRootConfigClasses()는 root-context.xml을 대신하는 클래스를 지정한다. 우리는 방금 만들었던 RootConfig 클래스를 작성하기 때문에 메소드의 내용을 변경한다.

@Override

protected Class<?>[] getRootConfigClasses() {

return new Class[] {RootConfig.class};

}

이제 톰캣을 실행해보면 로그가 바뀐 것을 알 수 있다.

INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcher': initialization started

INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Refreshing WebApplicationContext for namespace 'dispatcher-servlet': startup date [Tue Apr 30 02:34:37 KST 2019]; parent: Root WebApplicationContext

INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring

INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: WebApplicationContext for namespace 'dispatcher-servlet': startup date [Tue Apr 30 02:34:37 KST 2019]; parent: Root WebApplicationContext

INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcher': initialization completed in 374 ms

but... 404 에러가 난다

6. Java 설정에서 의존성을 주입한다. RootConfig.class 수정

@Configuration

@ComponentScan(basePackages= {"kr.co.myportfolio"})

public class RootConfig {


}

이 때 알아야 할 것은 스프링이 동작하면서 생기는 일인데 스프링프레임워크가 시작되면 스프링이 사용하는 메모리 영역을 만든다. 이를 context라고 하는데 스프링에서는 ApplicationContext라는 이름의 객체가 만들어진다. 스프링은 객체를 생성하고 관리해야 하는 것들에 대한 설정이 필요하다. 이 설정을  RootConfig 에서 한다. 여기에서 설정되어있는 @ComponentScan을 통해서 kr.co.myportfolio 패키지를 scan한다. 이 클래스들 중에 스프링이 사용하는 @Component 라는 어노테이션이 존재하는 클래스의 인스턴스를 생성한다.

7. servlet-context를 대신하는 ServletConfig.class 클래스를 작성한다. 이것은 기존에 servlet-context.xml에 설정된 모든 내용을 담아야 한다. 이 때 다음과 같은 방식을 이용하는데 

7-1) @EnableWebMvc 어노테이션과 WebMvcConfigurer 인터페이스를 구현하는 방식

7-2) @Configuration과 WebMvcConfigurationSupport 클래스를 상속하는 방식 이다.

나는 @EnableWebMvc 어노테이션을 이용해서 만든다.

8. ServletConfig.class를 만든다. servlet-config.xml 대신 만드는 것

@Configuration

@ComponentScan(basePackages="kr.co.portfolio.**")

public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer{


@Override

protected Class<?>[] getRootConfigClasses() {

// TODO Auto-generated method stub

return new Class[] {RootConfig.class};

}


@Override

protected Class<?>[] getServletConfigClasses() {

// TODO Auto-generated method stub

return new Class[] {ServletConfig.class};

}


@Override

protected String[] getServletMappings() {

// TODO Auto-generated method stub

return new String[]{"/"};

}


}

9. WebConfig 내용을 수정한다.

@Configuration

@ComponentScan(basePackages="kr.co.portfolio.**")

public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer{


@Override

protected Class<?>[] getRootConfigClasses() {

// TODO Auto-generated method stub

return new Class[] {RootConfig.class};

}


@Override

protected Class<?>[] getServletConfigClasses() {

// TODO Auto-generated method stub

return new Class[] {ServletConfig.class};

}


@Override

protected String[] getServletMappings() {

// TODO Auto-generated method stub

return new String[]{"/"};

}


}



이제 404에러가 해결되었다.