Spring Framework 핵심 개념 정리

Spring Framework의 기본 구조

Spring은 단순한 프레임워크가 아니라, 다양한 기능을 제공하는 컨테이너 기반의 개발 플랫폼이다. 이는 의존성 주입(DI), AOP, 트랜잭션 관리 등 핵심 기능을 통합적으로 제공한다.

1. Spring 컨테이너 구성

Spring 컨테이너는 애플리케이션의 핵심 객체를 관리하는 역할을 수행하며, 일반적으로 하나의 인스턴스만 생성하여 사용한다. 리소스 소모가 크기 때문에 최적화된 설계가 필요하다.

2. 클래스 경로 및 리소스 로딩

기본적으로 src 디렉터리가 클래스 경로로 설정되지만, 실행 시에는 out 디렉터리의 컴파일된 결과물이 실제 경로로 사용된다. 리소스 접근 방식은 두 가지가 존재한다:

  • Class.getResource(): 절대 경로(/)를 사용해 프로젝트 루트를 지정할 수 있음
  • ClassLoader.getResource(): 상대 경로만 허용되며, 절대 경로(/) 사용 시 null 반환됨

3. 리소스 스트림 읽기 방법 비교

다음은 자주 사용되는 리소스 로딩 패턴:

// 클래스 내부 리소스
InputStream stream1 = MyClass.class.getResourceAsStream("config.properties");

// 클래스 로더 기반 리소스 (상대 경로)
InputStream stream2 = MyClass.class.getClassLoader().getResourceAsStream("config.properties");

// 클래스 로더 기반 리소스 (절대 경로 - 오류 발생 가능)
InputStream stream3 = MyClass.class.getClassLoader().getResourceAsStream("/config.properties");

4. 동적 프록시 기술 차이점

자바에서 제공하는 두 가지 프록시 기법:

  • JDK 프록시: 인터페이스 기반. 인터페이스에 정의된 메서드만 감쌀 수 있음
  • CGLIB 프록시: 부모 클래스 기반. 모든 메서드(인터페이스 포함)를 감쌀 수 있음

5. 어노테이션 처리 주의사항

어노테이션 검사 시 다음과 같은 오류를 피해야 한다:

// 잘못된 예:
if (field.isAnnotationPresent(@Autowired.class)) { ... }

// 올바른 예:
if (field.isAnnotationPresent(Autowired.class)) { ... }

6. 트랜잭션 관리 설정 방법

선언형 트랜잭션은 두 가지 방식으로 활성화할 수 있다:

  • XML 기반: ``
  • Java Config 기반: @EnableTransactionManagement 어노테이션 사용

둘 다 내부적으로 DataSourceTransactionManager를 통해 트랜잭션을 제어한다.

7. 리소스 경로 추출 팁

URL 객체로부터 파일 경로를 추출할 때 다음 메서드를 활용:

URL resource = getClass().getResource("/");
String path = resource.getPath();     // /D:/project/out/...
String file = resource.getFile();     // D:/project/out/...

8. 예외 처리 대체 전략

메서드에서 값을 반환하지 않고 예외를 던지는 것도 유효한 패턴:

public Object getBean(String name) {
    throw new NoSuchBeanException("Bean not found: " + name);
    // return null; 생략 가능
}

9. 인터페이스 확인 방법

클래스가 특정 인터페이스를 구현했는지 확인하는 방법:

// 클래스 객체 확인
boolean implementsInterface = SomeInterface.class.isAssignableFrom(clazz);

// 인스턴스 확인
boolean instanceCheck = instance instanceof SomeInterface;

10. 반복적인 트랜잭션 문제 해결

중첩 트랜잭션에서 데드락이 발생하면, 데이터베이스의 잠금 타임아웃 설정을 확인하고, 트랜잭션 범위를 조정하거나 재시도 로직을 추가해야 한다.

태그: Spring Framework IoC Container Dependency Injection AOP Dynamic proxy

8월 2일 15:39에 게시됨