Q. Spring에서 AOP(Aspect Oriented Programming)가 필요한 이유와 이를 활용한 실제 애플리케이션 개발 사례에 대해 설명하세요.
System.out.println()을 넣으면 중복 + 유지보수 불편...@Aspect
@Component
public class LogAspect {
@Around("execution(* com.myapp.service..*(..))")
public Object logExecutionTime(ProceedingJoinPoint joinPoint)
throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long end = System.currentTimeMillis();
System.out.println("실행시간: " + (end - start) + "ms");
return result;
}
}
@Transactional):@Transactional만 붙이면,1) eGovFrame의 AOP 설계와 적용 기본 개념
핵심 비즈니스 로직(주업무 코드)과 별개로, 트랜잭션, 로깅, 보안검증, 권한 관리 등 "공통 부가기능" 을 핵심 코드와 분리해서 모듈화 적용하는 기법을 사용했다.
2) eGovFrame에서의 AOP 목표
a. 비즈니스 로직과 부가 concern(관심사)분리
b. 공통코드의 중앙 집중화
c. 유지보수, 테스트 효율성 및 일관성 증대
try-catch-finally로 트랜잭션 컨트롤(1) Aspect 클래스를 두고 @Aspect, @Component 어노테이션 사용
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.egov.sample..*(..))")
public void beforeMethod(JoinPoint joinPoint) {
// 메서드 시작 전 실행
System.out.println("진입: " + joinPoint.getSignature());
}
@AfterReturning(pointcut="execution(* com.egov.sample..*(..))",
returning="result")
public void afterReturning(JoinPoint joinPoint, Object result) {
System.out.println("종료: " + joinPoint.getSignature() + " 반환값: " + result);
}
}
(2) 트랜잭션이나 Role, Exception Advice도 같은 방식으로 구현
<aop:aspectj-autoproxy/>@EnableAspectJAutoProxyEgovAbstractServiceImpl등 여러 Service에서 AOP가 자동 적용<aop:aspectj-autoproxy />
<bean id="loggingAspect" class="egovframework.example.LoggingAspect"/> <aop:config>
<aop:aspect ref="loggingAspect">
<aop:pointcut id="allServiceOperation" expression="execution(* com.egov..service.*.*(..))"/>
<aop:before pointcut-ref="allServiceOperation" method="beforeMethod"/>
</aop:aspect>
</aop:config>
<참고:egovframework:rte:fdl:aop:egovrteaopguide [eGovFrame]>
/users/1 GET 요청)@Controller 또는 @RestController 어노테이션이 붙음Q. Spring MVC에서 클라이언트의 요청 처리 흐름을 @Controller와 @RestController의 차이점을 중심으로 각각의 처리 과정과 특징을 포함하여 설명하세오.
@Controller의 처리 과정과 특징"userList" 또는 ModelAndView)은 뷰 이름(템플릿 파일명)으로 해석된다.@ResponseBody를 추가해야 한다.@Controller
public class UserController {
@GetMapping("/users")
public String userList(Model model) {
List<User> users = userService.findAll();
model.addAttribute("users", users);
return "users/list"; // 뷰 이름 반환
}
}
/users 요청 → "users/list.html" 등의 템플릿이 렌더링되어 HTML로 응답된다.특징
@ResponseBody 또는 메서드 단위에 @ResponseBody를 붙여야 한다.@RestController의 처리 과정과 특징@RestController
public class UserRestController {
@GetMapping("/api/users")
public List<User> list() {
return userService.findAll();
}
}
/api/users 요청 → List<User>가 자동으로 JSON으로 변환되어 응답 바디에 담김(뷰 템플릿 없음)특징
| 항목 | @Controller | @RestController |
|---|---|---|
| 반환값 의미 | 뷰 이름(템플릿 경로) | 응답 데이터(객체 자체) |
| 활용 목적 | 웹페이지 렌더링 | REST API, JSON 등 데이터 응답 |
| @ResponseBody | 메서드별로 직접 붙여줘야 함 | 자동 적용됨(모든 메서드에 포함됨) |
| 반환 예 | "users/list" (뷰명) | User, List 등 객체(→JSON) |
@Controller는 주로 웹페이지(HTML 뷰) 렌더링에,@RestController는 주로 JSON 등 데이터 응답이 필요한 API 서버에 사용된다는 점이 핵심이다.