ApplicationContext vs DispatcherServlet : 컨텍스트 간의 관계

웹쪽 자원을 관리하는 DispatcherServlet과 그 외의 자원을 관리하는 ApplicationContext는 어떤 관계가 있을까? 예제에서는 DispatcherServlet과 ApplicationContext의 정보를 가져오기 위해 ApplicationContextAware를 구현한 클래스를 양쪽에 등록하고, 두 컨텍스트의 정보를 출력해봤다.

ApplicationContextHolder.java


package com.tistory.jekalmin.common;


import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;


public class ApplicationContextHolder implements ApplicationContextAware{

@Override

public void setApplicationContext(ApplicationContext ctx)

throws BeansException {

System.out.println("================================================");

System.out.println("applicationContext : " + ctx.getId());

System.out.println("applicationContext hashCode : " + ctx.hashCode());

ApplicationContext parent = ctx.getParent();

if(parent != null){

System.out.println("parent : " + parent.getId());

System.out.println("parent hashCode : " + parent.hashCode());

}

System.out.println("================================================");

}


}



web.xml


<context-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>

        classpath:spring/application-context.xml

        </param-value>

    </context-param>


    <listener>

        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

    </listener>

    

    <servlet>

        <servlet-name>dispatcherServlet</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <init-param>

            <param-name>contextConfigLocation</param-name>

            <param-value>classpath:spring/spring-servlet.xml</param-value>

        </init-param>

        <load-on-startup>1</load-on-startup>

    </servlet>


결과는 다음과 같다.


================================================ applicationContext : org.springframework.web.context.WebApplicationContext: applicationContext hashCode : 966881334 ================================================ ================================================ applicationContext : org.springframework.web.context.WebApplicationContext:/dispatcherServlet applicationContext hashCode : 1233412676 parent : org.springframework.web.context.WebApplicationContext:/SpringTest parent hashCode : 966881334 ================================================


applicationContext 먼저 생성되고, dispatcherServlet은 applicationContext를 부모로 가지고 있는다.

여러개의 Spring xml 설정파일, ApplicationContext는 몇개인가

보통 스프링 프로젝트를 만들 때 xml 기반으로 ApplicationContext를 생성하는 경우가 많다. 그리고 스프링 설정파일들도 ContextLoaderListener 라는 리스너에 여러개 등록할 수 있는데, 과연 이 경우에 컨텍스트가 여러개 생셩되는지, 하나의 컨텍스트가 생성되는 지 궁금했다. 

결론부터 말하자면 리스너에 아무리 많은 xml 파일들을 등록해도 하나의 ApplicationContext만 올라간다. 

아래 예제에서는 bean을 생성해준 컨텍스트 정보를 알 수 있도록 ApplicationContextAware를 구현한 클래스를 양쪽 xml에 등록하고 컨텍스트 정보를 출력해서 비교하였다.


web.xml


<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>

    classpath:spring/application-context.xml

    classpath:spring/spring-security.xml

    </param-value>

</context-param>

application-context.xml


<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.tistory"></context:component-scan>

    <bean class="com.tistory.jekalmin.common.ApplicationContextHolder"/>

</beans>


spring-security.xml


<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    

    <bean class="com.tistory.jekalmin.common.ApplicationContextHolder"/>


</beans>


ApplicationContextHolder.java


package com.tistory.jekalmin.common;


import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;


public class ApplicationContextHolder implements ApplicationContextAware{

@Override

public void setApplicationContext(ApplicationContext ctx)

throws BeansException {

System.out.println("applicationContext : " + ctx);

System.out.println("applicationContext hashCode : " + ctx.hashCode());

}


}


결과는 다음과 같다.


applicationContext : Root WebApplicationContext: startup date [Tue Sep 30 10:27:17 EDT 2014]; root of context hierarchy

applicationContext hashCode : 12545140

applicationContext : Root WebApplicationContext: startup date [Tue Sep 30 10:27:17 EDT 2014]; root of context hierarchy

applicationContext hashCode : 12545140





두개의 다른 xml에서 ApplicationContextAware를 구현한 클래스를 등록하고 hashCode를 출력하였는데, 같은 객체임을 알 수 있다.

sublime enter키 수정

이클립스의 자바쪽에서 auto-complete을 이용해 파라미터를 입력한 후 enter키를 누르면 End키를 눌렀을 때처럼 커서가 줄의 마지막으로 이동하는데, 이것에 익숙해져있다보니 sublime에서도 하고싶어서 검색하다가 비슷한 것을 발견했다.


[

  { "keys": ["enter"], "command": "move_to", "args": {"to": "eol", "extend": false}, "context":

    [

        { "key": "following_text", "operator": "regex_contains", "operand": "^[)\\]'\"]", "match_all": true },

        { "key": "preceding_text", "operator": "regex_contains", "operand": "[(['\"]", "match_all": true },

        { "key": "auto_complete_visible", "operator": "equal", "operand": false }

    ]

  }

]

이 코드를 서브라임에서 Preferences > Key Bindings - User 안에 붙여넣으면 된다.

만약 정말 줄바꿈이 하고 싶을 때는 Shift + Enter 를 사용하면 된다.

참고 : https://coderwall.com/p/td7e-w