오늘은 Java Config 방식으로 AOP(Aspect-Oriented Programming)를 활용해 예외 처리를 구현하는 웹 애플리케이션을 직접 만들어보았습니다. 기존의 XML 설정 방식과 Annotation 기반 방식과 비교하며, Java 코드만으로 설정을 처리할 수 있는 장점도 함께 느껴볼 수 있었어요.
1️⃣ 프로젝트 구조
java-config-version/
├── src/
│ └── main/
│ ├── java/
│ │ └── com/example/javaconfig/
│ │ ├── App.java
│ │ ├── AppConfig.java
│ │ ├── Calculator.java
│ │ ├── LoggingAspect.java
│ │ └── WebAppInitializer.java
└── pom.xml
2️⃣ pom.xml (필수 의존성)
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.30</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.30</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.20.1</version>
</dependency>
</dependencies>
3️⃣ AppConfig.java (설정 클래스)
package com.example.javaconfig;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration // 설정 클래스임을 명시
@ComponentScan("com.example.javaconfig") // 해당 패키지 하위 컴포넌트 자동 탐색
@EnableAspectJAutoProxy // AOP 기능을 활성화
public class AppConfig {
}
✅ XML 설정 없이 자바 코드로 모든 설정을 해결합니다.
4️⃣ Calculator.java (비즈니스 로직 클래스)
package com.example.javaconfig;
import org.springframework.stereotype.Component;
@Component // 스프링이 관리할 수 있도록 등록
public class Calculator {
public int divide(int a, int b) {
return a / b; // 0으로 나누면 예외 발생
}
}
5️⃣ LoggingAspect.java (AOP 예외 로깅)
package com.example.javaconfig;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.io.FileWriter;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Aspect // 이 클래스가 AOP 역할을 한다는 표시
@Component // Bean으로 등록
public class LoggingAspect {
// 예외 발생 후 실행되는 어드바이스
@AfterThrowing(pointcut = "execution(* com.example.javaconfig.Calculator.*(..))", throwing = "ex")
public void logException(Exception ex) {
try {
// 현재 시간을 포맷팅
String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
FileWriter writer = new FileWriter("log_" + timestamp + ".txt");
writer.write("에러 발생: " + ex.getMessage());
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
✅ @AfterThrowing은 예외가 발생했을 때 특정 메서드(logException)가 실행되게 합니다.
6️⃣ WebAppInitializer.java (웹 어플리케이션 초기화 설정)
package com.example.javaconfig;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
public class WebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
// 자바 설정 기반 컨텍스트 생성
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(AppConfig.class); // 설정 클래스 등록
// DispatcherServlet 생성 및 설정
DispatcherServlet servlet = new DispatcherServlet(context);
ServletRegistration.Dynamic registration = container.addServlet("dispatcher", servlet);
registration.setLoadOnStartup(1); // 서버 시작 시 서블릿 로딩
registration.addMapping("/"); // 루트 경로에 매핑
}
}
✅ 웹.xml 없이 웹 애플리케이션 초기화 가능하게 해줍니다.
7️⃣ App.java (테스트용 실행 클래스)
package com.example.javaconfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App {
public static void main(String[] args) {
// 자바 설정 기반의 컨텍스트 생성
var context = new AnnotationConfigApplicationContext(AppConfig.class);
// Calculator 빈 가져오기
Calculator calculator = context.getBean(Calculator.class);
try {
// 예외 유발 (0으로 나누기)
calculator.divide(10, 0);
} catch (Exception e) {
System.out.println("예외 발생 (메인): " + e.getMessage());
}
}
}
✨ 요약
항목 내용
학습 주제 | Java Config 방식 AOP 예외처리 |
주요 기능 | @Aspect, @AfterThrowing, Java Config 기반 설정 |
사용 기술 | Spring Context, Spring AOP, AspectJ |
설정 방식 | XML 없이 전부 Java로 설정 |
테스트 방식 | divide(10, 0) 실행 시 로그파일 생성됨 |
💭 부족했던 점
- 처음에는 WebAppInitializer가 꼭 필요한지 헷갈렸고, DispatcherServlet 설정도 익숙하지 않았습니다.
- AOP의 pointcut 표현식이 익숙하지 않아 자꾸 오타가 났습니다.
🔧 개선할 점
- AOP 표현식을 더 다양한 예제로 연습해보아야겠습니다.
- 예외 로그 파일을 한 개만 사용하고 로그 누적 방식으로도 개선할 수 있을 것 같습니다.
📍 마무리
XML 없이 Java로만 설정하는 방식은 코드 관리가 쉬워지고 IDE의 도움을 받을 수 있어 좋았습니다.
AOP를 이용해 예외 처리 흐름을 분리하는 것도 실무에서 유용할 것 같아요.
'Spring' 카테고리의 다른 글
📅 2025년 4월 14일 - Spring 프로젝트에서 HttpServletRequest 오류 해결하기 (0) | 2025.04.14 |
---|---|
[2025-04-08] 스프링 AOP를 이용한 예외 로그 기록 자동화 실습 (0) | 2025.04.08 |
📅 2025년 3월 31일 - Spring AOP(XML 설정)으로 출근/퇴근 자동화하기! (0) | 2025.03.31 |
🌱 스프링 의존성 주입(DI) 3가지 방식 완전 정리 (2025.03.24) (0) | 2025.03.24 |
📘 2025년 3월 16일 교차 검증과 그리드 서치(Grid Search)로 최적의 모델 찾기 (0) | 2025.03.16 |