2019년 1월 시점 아래 글은 이제 오래된 글입니다.
https://start.spring.io/ 스프링 Initializer를 이용해보세요.
-----
스터디 소스 출처: http://projects.spring.io/spring-framework/
환경
자바환경: Java 1.7.0_45
개발환경: Eclipse Java EE IDE for Web Developers. (Kepler Service Release 1 ; 4.3)
스프링환경: STS를 사용하지 않고 Spring IDE를 설치하여 사용
( http://spring.io/tools/sts/all 에 있는 Update Sites http://dist.springsource.com/release/TOOLS/update/e4.3/ 를 이용)
소스코드 : IoC에 대한 이해를 위해 만들어진 것 같음
이클립스 프로젝트 생성하기
원래 Gradle로 하려고 했는데 STS 툴 자체가 Maven 기반으로 되어 있다보니 우선은 있는 데로 하기로 했다.
New > Projet > Spring > Spring Starter Project : 선택하고 'Next' 버튼.
New Spring Starter Project : 아래 빨간색을 채워넣고 'Finish'버튼.
기본적으로 src/main/java/hello와 src/test/java/hello 아래 java 파일이 있는데 지운다.
pom.xml 파일을 열어 모두 지운다.
QuickStart에 보면 Maven 정보가 있다.
이 정보를 바탕으로 의존 속성(Dependency Property) 추가를 해준다.
이제 http://projects.spring.io/spring-framework/#quick-start 에 있는대로 소스코드를 만들어 본다.
프로그래머 인생이 녹녹치 않듯 실행을 하면 아래와 같이 에러가 난다. 또한 ApplicationContext context 부분에는 경고도 있다.
commons-logging 의존성
의존성을 끊어주기 위한 프레임워크가 다른 라이브러리에 의존을 하고 있다니, 좀 아이러니 하긴한데,, 사실 스프링이 없애려고 하는 의존성은 애플리케이션에 대한 것이니 논외로 하고...
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.springframework.context.support.AbstractApplicationContext.<init>(AbstractApplicationContext.java:153)
at org.springframework.context.support.GenericApplicationContext.<init>(GenericApplicationContext.java:100)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:60)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:82)
at hello.Application.main(Application.java:22)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 5 more
에러를 따라 StackTrace 해보면 AbstractApplicationContext가 범인이다.
스프링 프레임워크가 의존하는 다른 라이브러리가 있다니...
Maven (pom.xml)에 commons-logging 에 대한 의존성을 추가해 준다.
정보는 http://mvnrepository.com/artifact/commons-logging/commons-logging 를 참고한다.
다시 실행해보면... Hello World가 찍힌다.
거슬리는 Warning
한가지 거슬리는 것은 앞서 언급한 Warning이다.
quick fixes가 추천해준 @SuppressWarnings를 붙이고 싶은 욕구가 불끈불끈 솟는다.
이클립스가 경고를 띄어주는 이유는 AnnotationConfigApplicationContext가 (사실 부모..부모...가) Closeable를 상속받았기 때문이다.
관련 사항은 Eclipse documentation를 참고하면 알 수 있다.
자바 1.5의 java.io.Closeable 인터페이스나 자바 1.7의 java.lang.AutoCloseable 인터페이스를 구현한 클래스들을 close()를 호출하지 않으면 리소스 누수가 발생할 수 있기에 경고를 해주는 것이라고 한다. (요약은 여기서)
그런데 ApplicationContext에는 눈을 씻고 찾아봐도 close() 메소드가 없다. 원인 제공자인 AnnotationConfigApplicationContext 때문에 발생하는 것을 ApplicationContext에 왜 없냐고 묻는 것은 우물가에서 숭늉찾는 격인 것이다. 클래스의 계층을 살펴보면 아래와 같다.
class AnnotationConfigApplicationContext extends GenericApplicationContext
↓
class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry
↓
abstract
class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean {
// ...
@Override
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
// If we registered a JVM shutdown hook, we don't need it anymore now:
// We've already explicitly closed the context.
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
}
}
// ...
}
↓
interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable
보면 AbstractApplicationContext에서 close를 구현하고 있다. 또한 Closeable를 상속한 직계 인터페이스는 ConfigurableApplicationContext라는 것도 알 수 있다. (이놈이 원인이여.. 이클립스는 참 대단해. 이런 것을 참 빨리도 찾네)
다시 원래대로 돌아가서...
ApplicationContext를 ConfigurableApplicationContext로 다운캐스팅을 하면 close()가 가능해진다. (출처)
수행을 해보면 "Hello World!" 아래에 doClose가 호출되는 빨간색 메세지가 추가되었음을 알 수 있다.
최종 소스는 => SpringFrameworkQuickStart.zip (다행히 10M가 안되어서...)
- Don't Repeat Yourself [본문으로]
'Programing > JVM(Java, Kotlin)' 카테고리의 다른 글
[JVM] PermGen? (0) | 2014.01.22 |
---|---|
Live Webinar Series - Introduction to Spring Framework 4.0 (0) | 2014.01.11 |
스프링에서 요청파라메터 처리하기 (0) | 2014.01.07 |
2014년 스프링 학습 (목록) (0) | 2014.01.07 |
이클립스의 자바빈 getter/setter 생성 버그 (0) | 2013.05.24 |