ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [spring] 자바 Config 설정하기 vs XML 설정하기
    Spring 2020. 3. 10. 00:34
    반응형
    Spring Framework는 설정이 반이라는 말이 있다.
    그만큼 초기 설정 방법도 여러 가지고 복잡하기 때문에 이런 말이 나왔을 거라 생각한다. (스프링 부트를 이용해서 간단하게 설정하는 해결하는 방법도 있구..) 기본적인 XML을 통한 설정과 자바 Annotation을 통한 설정 두 가지를 정리해보자.

     

    XML을 통한 스프링 설정


    web.xml

    Deployment Descriptor(배포 서술자) 라고 불리며 웹페이지의 환경설정 부분을 담당한다. 
    WAS(Web Application Server)가 최초 구동될 때 web.xml을 읽고 그에 해당하는 설정을 구성한다.

    설정을 위한 설정파일이 되는 셈이다. 

     

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    
    <!-- ========================= [default] ======================================= -->
    
    <!-- Root WebApplicationContext 설정(부모) -->
    <!-- Application 전반적인 공유의 목적으로 사용되는 설정을 포함(DB연결, 로깅 등) -->
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>
    
    <!-- ContextLoaderListener 클래스를 통해 Root WebApplicationContext 영역을 구성 -->
    <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!-- Servlet WebApplicationContext 설정(자식) -->
    <!-- DispatcherServlet 선언을 통해 servlet 관련 설정을 포함 -->
    <servlet>
      <servlet-name>appServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 초기 파라미터 이름을 Root WebApplicationContext와 일치시켜 주고 상속받음  -->
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
      <load-on-startup>1</load-on-startup>
    </servlet>
    
    <!-- 모든 경로에 대한 요청을 DispatcherServlet에게 위임 -->
    <servlet-mapping>
      <servlet-name>appServlet</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <!-- ========================= [default] ======================================= -->
    
    <!-- ========================= [추가 설정] ====================================== -->
    
    <!-- 서버에 요청이 들어왔을 때 처음 보여지는 페이지 설정 -->
    <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    
    <!-- 한글 인코딩 필터 설정 'encodingFilter' -->
    <filter>
      <filter-name>encodingFilter</filter-name>
        <filter-class>
          org.springframework.web.filter.CharacterEncodingFilter     
        </filter-class>
      <init-param>
        <param-name>encoding</param-name>   
        <param-value>UTF-8</param-value>
      </init-param>
      <init-param>
        <param-name>forceEncoding</param-name>  
        <param-value>true</param-value>
      </init-param>
    </filter>    
    
    <!-- 모든 경로에 대한 요청을 'encodingFilter' 에게 위임 -->
    <filter-mapping>
      <filter-name>encodingFilter</filter-name>
      <url-pattern>/*</url-pattern>                 
    </filter-mapping>
    
    <!-- 세션 유지 설정 (분 단위) -->
    <session-config>
      <session-timeout>3</session-timeout>
    </session-config>
    
    <!-- 에러페이지 설정 -->
    <error-page>
      <error-code>401</error-code>
      <location>/resources/commons/error/serverError.jsp</location>
    </error-page>
    
    <error-page>
      <error-code>500</error-code>
      <location>/resources/commons/error/serverError.jsp</location>
    </error-page>
    
    <!-- ========================= [추가 설정] ====================================== -->
    
    </web-app>

    스프링의 WebApplicationContext의 계층 관계는 부모-자식 관계로 이루어진 두 개의 컨텍스트가 존재한다.

    ContextLoaderListener가 부모의 역할을 수행하는 Root WebApplicationContext를 생성하고

    DispatDispatcherServlet은 자식의 역할로서 부모를 상속받아 사용하는 Servlet WebApplicationContext를 생성한다.

     

    Root WebApplicationContextContextLoaderListener에 의해 생성되며, Application 전역에서 사용 가능한  WebApplicationContext이며, 서비스 계층이나 DAO, DB를 포함한 웹 환경의 설정을 담당하다. (공유의 목적)

     

    Servlet WebApplicationContext는 DispatDispatcherServlet에 의해 생성되며 해당 servlet에서만 사용이 가능하며 Controller, ViewResolver, HandlerMapping 같은 서블릿 차원의 빈 객체 설정을 모아두는 설정 공간이다.

     

    루트와 서블릿 컨텍스트는 공통적으로 <param-name>을 'contextConfigLocation' 으로 동일하게 맞춰줌으로써 상속관계를 가지게 되고 스프링에서 사용되는 컨텍스트 계층 관계를 연결한다.

    (정확하게 DispatDispatcherServlet은 ContextLoaderListener에 의해 Root WebApplicationContext를 상속받고 Servlet WebApplicationContext를 생성한다.)

     

    servlet-context.xml

    Servlet WebApplicationContext가 참조하는 설정 모음.

    view와 관련있는 빈 객체를 설정(controller, MultipartResolver, Interceptor 등..)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:beans="http://www.springframework.org/schema/beans"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
    		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
    	
    <!-- 자바 어노테이션 활설화 -->
    <annotation-driven />
    
    <!-- 
    정적 데이터(html, css, js, images) 접근 
    경로를 '/' 로 지정하고 나서 모든 요청을 DispatcherServlet이 처리하기 때문에
    자원에 대한 접근을 인터셉트
    -->
    <resources mapping="/resources/**" location="/resources/" />
    
    <!-- 뷰 리졸버 생성 및 prefix, suffix 설정 -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <beans:property name="prefix" value="/WEB-INF/views/" />
      <beans:property name="suffix" value=".jsp" />
    </beans:bean>
    
    <!-- Component 패키지 범위 설정 -->
    <context:component-scan base-package="xyz.devyu.spring" />
    	
    </beans:beans>
    

     

    root-context.xml

    Root WebApplicationContext가 참조하는 설정 모음.

    view와 관련없는 객체(bean)를 설정. (service, repository, dao, DB 등..)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:beans="http://www.springframework.org/schema/beans"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
    		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
    <!-- database 관련 설정 -->
    <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <beans:property name="driverClassName" value="com.mysql.jdbc.Driver"></beans:property>
      <beans:property name="url" value="jdbc:mysql://127.0.0.1:3306/스키마"></beans:property>
      <beans:property name="username" value="아이디"></beans:property>
      <beans:property name="password" value="비밀번호"></beans:property>
    </beans:bean>
    	
    </beans:beans>
    

     

    자바 Config를 통한 스프링 설정


    기존의 xml으로 이루어진 설정파일을 Java 코드로 변경하는 가장 큰 이유는 디버깅 시 문제를 보다 쉽게 파악할 수 있게 때문이다.

     

    pom.xml
    <!-- default 2.5 ver -> 3.1.0 ver 변경 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <!-- web.xml 없이 Java 설정으로만 -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-war-plugin</artifactId>
      <configuration>
        <failOnMissingWebXml>false</failOnMissingWebXml>
      </configuration>
    </plugin>

    spring 3.2, servlet version은 3.0 이상을 사용해야 하고 xml을 사용하지 않는다는 plugin을 추가한다

     

    WebInitializer.java.

    web.xml을 대체한 Java파일

    public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    	// Root WebApplicationContext
    	@Override
    	protected Class<?>[] getRootConfigClasses() {
    		return new Class[] { RootContext.class };
    	}
    
    	// Servlet WebApplicationContext
    	@Override
    	protected Class<?>[] getServletConfigClasses() {
    		return new Class[] { ServletContext.class };
    	}
    	
        // DispatcherServlet Mapping
    	@Override
    	protected String[] getServletMappings() {
    		return new String[] { "/" };
    	}
    
    	// filter
    	@Override
        protected Filter[] getServletFilters() {
            CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
            characterEncodingFilter.setEncoding("UTF-8");
            characterEncodingFilter.setForceEncoding(true);
    
            return new Filter[] { characterEncodingFilter };
        }
    }

     

    ServletContext.java

    servlet-context.xml을 대체한 파일

    @Configuration
    @EnableWebMvc
    @ComponentScan("xyz.devyu.spring")
    public class ServletContext implements WebMvcConfigurer {
    
    	@Override
    	public void addResourceHandlers(ResourceHandlerRegistry registry) {
    		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    	}
    
    	@Bean
    	public InternalResourceViewResolver resolver() {
    		InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    		resolver.setViewClass(JstlView.class);
    		resolver.setPrefix("/WEB-INF/views/");
    		resolver.setSuffix(".jsp");
    		return resolver;
    	}
    }
    

     

    RootContext.java

    root-context.xml을 대체한 파일

    @Configuration
    public class RootContext {
    	
    	@Bean
    	public DataSource dataSource() {
    		DriverManagerDataSource dataSource = new DriverManagerDataSource();
    		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    		dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/스키마");
    		dataSource.setUsername("아이디");
    		dataSource.setPassword("비밀번호");
    		return dataSource;
    	}
    }

     

     

     

     

     

     

     

    반응형

    댓글

Designed by Tistory.