Spring JavaConfig냐 XML 설정이냐 프로그래밍

Spring 설정을 할 때 JavaConfig를 사용하는 것이 좋을까 XML 설정을 하는 것이 좋을까?
흔히 JavaConfig를 사용하자고 하는 말하는 사람들은 Java로 작성하면 정적 언어 특징 덕분에 작성 중 컴파일을 통해 에러를 쉽게 찾고 리팩토링도 안전하게 할 수 있어서 실수 위험이 줄어들기 때문에 XML보다는 Java가 더 낫다고 말한다.

그럼 아래의 XML 설정과 JavaConfig 설정을 살펴보자.(참고로 나는 이제 Commons DBCP를 더이상 사용하지 않는다. BoneCP를 주로 사용하려고 한다.)
<bean id="datasource"
 class="org.apache.commons.dbcp.BasicDataSource"
    p:driverClassName="${jdbc.driverClassName}" 
    p:url="${jdbc.url}"
    p:username="${jdbc.username}" 
    p:password="${jdbc.password}"
    p:maxActive="${jdbc.maxActive}"
    p:maxWait="${jdbc.maxWait}"
    p:validationQuery="${jdbc.validationQuery}"
    p:testWhileIdle="${jdbc.testWhileIdle}"
    p:timeBetweenEvictionRunsMillis="${jdbc.timeBetweenEvictionRunsMillims}"/>

@Value("${jdbc.driverClassName}")
private String driverClassName;

@Value("${jdbc.url}")
private String url;

// .. 너무 길어 생략

@Bean
public DataSource datasource() {
    BasicDataSource datasource = new BasicDataSource();
    datasource.setDriverClassName(driverClassName);
    datasource.setUrl(url);
    datasource.setUsername(username);
    datasource.setPassword(password);
    datasource.setMaxActive(maxActive);
    datasource.setMaxWait(maxWait);
    datasource.setValidationQuery(validationQuery);
    datasource.setTestWhileIdle(testWhileIdle);
    datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);

    return datasource;
}


어떤게 가독성이 높고 합리적이라 생각되는가? 내가 보기엔 XML이 훨씬 가독성이 높고 합리적으로 보인다. 또한 과연 우리가 BasicDataSource 클래스를 클래스로 직접 참조하거나 리팩토링할 가능성은? 여기서는 Java의 정적인 특징이 아무 의미가 없다.

나도 안다. 이게 좀 극단적인 예라는 것을. 문제는 Spring으로 설정을 하다보면 실제로 설정 XML로 빼는 것들은 보통 개발자가 직접 만든 코드보다는 저런 인프라성 객체 생성일 경우가 더 많다는 점이다.

그렇다면 나는 JavaConfig에 반대하는가? 그렇지 않다.
다만 JavaConfig라고 부르기보다는 CodeConfig라고 불렀으면 좋겠다는 점이다.

최근에 나는 Gradle을 사용하여 XML이 아닌 Groovy 코드로 빌드를 설정한다. 또한 로깅 프레임워크도 Logback을 사용하며, 이 설정도 XML이 아닌 Groovy로 하고 있다.
Groovy든 Java든 언어를 떠나서, 코드로 하는 설정의 특징을 살펴보자.
  • 코드는 그룹지어 클래스 혹은 메소드로 이름을 지어 분리가 가능하다.
  • 코드는 중복을 그룹지어 중복이 아닌 것은 인자로 받고 중복 부분은 클래스 혹은 메소드로 만들 수 있다.
  • 코드는 상황에 따른 대응을 더욱 쉽게 할 수 있다.

코드 기반 설정의 장점은 위 특징들에 있는 것이지 "정적"성에 있는 것이 아니다.

예를들어 위의 BasicDataSource 생성의 경우 나라면 아래와 같이 Factory를 만들어 중복이 되는 "jdbc.*"부분을 인자로 내려보내어 한번에 처리하게 할 것이다. BasicDataSourceFactory 내부에서는 Spring의 Environment 객체를 주입 받아서 "jdbc.driverClassName", "jdbc.url" 등의 값을 자동으로 가져다가 BasicDataSource 객체를 구성한다.우리는 수십개의 DataSource 객체를 생성해야 하는데, 각각의 DataSource를 다음과 같은 코드로 줄였다.
@Bean
public BasicDataSourceFactory datasource() {
    return new BasicDataSourceFactory("jdbc");
}


저렇게 중복을 제거하지 않더라도 단지 그루핑을 해서 메소드로 빼는 것만으로도 가치가 있다.

ᅟweb.xml은 그 XML의 향연이 볼 때마다 사람을 정신 못차리게 만드는 힘이 있는데, Servlet 3.0부터 Java 코드로 web.xml을 대체할 수 있게 하고 있다.
이때도 리스너 하나, 필터하나, 서블릿 하나 등을 그냥 Java 코드로 나열하지 말고 그룹지어 메소드로 뺀 뒤에 해당 메소드를 호출하는 형태로 만들면 가독성이 확연히 높아지게 된다.

현재 우리 팀에서 관리하고 있는 Logback 설정에서 가장 많이 중복되는 것은 RollingFileAppender 이다. 이 중에서도 일별 Rolling이 가장 많이 쓰인다. 이 어펜더는 다양한 옵션을 가지는데 대부분 패턴이 유사하다. 그래서 공통적인 사항을 메소드로 뽑고서 사실 가장 간결할 때는 다음 수준으로 호출해도 되게 만들었다.
dailyRollingAppender(name: 'somelog', file: '/logs/some.log')


상황에 따른 유연한 대응력도 코드 기반이 줄 수 있는 커다란 장점 중에 하나이다. 일반적으로 설정은 Profile별 분할은 하더라도 모든 개발자들이 똑같이 사용하는 것이 보통이다. 즉, Development 프로필의 설정이 모든 개발자들에게 동일하다는 점이다.
하지만 로깅을 예로 들면 어떤 개발자는 특정 부분의 로그를 더 자세히 찍고 싶을 때도 있을 것이다. 이때 development 프로필의 로깅 설정을 바꿨다가 실수로 저장소에 Push해서 다른 개발자들로부터의 원성을 사본 경험이 다들 있을 것이다.
이런 경우에도 개발자가 시스템 프라퍼티 세팅으로 자신만의 로그 설정파일을 임시로 사용하게 해주는 등의 처리가 코드를 통한 설정을 사용하면 쉽게 가능하다.(실제로 이렇게 만들었다).

이러한 유연성은 Profile에 따라 달라지는 무언가를 만들 때도 비슷하게 적용된다.

내가 보기엔 설정이라는 것이 앞으로는 설정 키/값을 가진 파일을 제외하고는 코드 기반으로 바뀌게 될 것으로 보인다. 이미 많은 부분들이 그렇게 바뀌었고. 개인적인 바람이라면 키/값 설정 파일도 XML이나 Java의 Properties 파일을 벗어나서 YML이 됐으면 좋겠다.
가끔 Spring 설정을 JavaConfig로 바꾸자는 주장을 보면 그 논리가 Java의 정적인 특성에 치우쳐져 있는 경우가 많다. 이는 맨 위에서 보여줬던 예제만으로도 쉽게 반대에 부딪히게 된다.
코드 기반 설정의 장점을 충분히 활용할 수 있도록 하자.

Spring의 Java Config 사용시 주의할 점

덧글

  • 악의곰푸우 2014/01/26 19:13 #

    Servlet 3.0부터 Java 코드로 web.xml을 대체할 수 있게 하고 있다. -> 이 부분은 스펙의 어느 부분을 보면 나오는지 궁금하네요
  • 권남 2014/01/26 20:13 #

  • 최빈 2014/03/05 15:38 # 삭제

    완전 공감합니다 ~!!
    Spring Configuration 이 대부분의 경우 편하긴 하지만 어떤면에선 오히려 직관적이지 못한것 같습니다.
  • 쯔앙구 2016/01/13 14:06 # 삭제

    글 내용하나하나가 다 디테일하네요.
  • 권남 2016/01/13 22:19 #

    고맙습니다.
※ 로그인 사용자만 덧글을 남길 수 있습니다.