일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 파이썬
- 패캠강의후기
- 환급챌린지
- 코딩교육
- 직장인자기계발
- 30개프로젝트로배우는iOS앱개발withSwift초격차패키지Online.
- 직장인인강
- 패스트캠퍼스
- 자바스크립트
- 자바
- 코딩자격증
- 패스트캠퍼스후기
- 패캠
- 패캠인강후기
- fastcampus
- 수강료0원챌린지
- 직장인공부
- 패캠챌린지
- 직정인자기계발
- 오공완
- 코딩테스트
- reactnative강의
- 패캠reactnative
- Today
- Total
라티의 작은 일기장
패스트캠퍼스 환급챌린지 1일차 미션 (2월 1일) : 10개 프로젝트로 시작하는 백엔드 웹개발 : 신입 개발자 취업 집중반 강의 후기 본문
패스트캠퍼스 환급챌린지 1일차 미션 (2월 1일) : 10개 프로젝트로 시작하는 백엔드 웹개발 : 신입 개발자 취업 집중반 강의 후기
코드라티 2025. 2. 1. 18:01본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.
얼마전 작성한 회고글에 백엔드 개발 공부를 시작하는 것을 다짐하는 내용을 썼었는데, 우연히도 패캠에서 환급챌린지 이벤트를 진행하는 것을 보고 냉큼 백엔드 강의로 챌린지를 시작했다. 기간은 한달, 이 기회에 백엔드 찍먹 열심히 해보자고~
나는 챌린지 시작일 이전부터 강의 수강을 시작했기 때문에, 오늘은 DI 실습 파트, AOP 개념 소개 클립을 보고 공부해봤다.
스프링은 Bean이라는 객체 또는 모듈(패키지) 단위로 의존성 주입이 가능한데, 요즘은 xml 기반의 의존성 주입 방식보다 자바 기반(Spring 3버전 이상) 또는 어노테이션 기반(Spring 2.5버전 이상)의 방식을 많이 사용한다고 한다.
의존성 주입(Dependency Injection)은 스프링 내부의 IoC 컨테이너에 등록된 Bean을 기반으로 해당 Bean의 의존하는 인스턴스에 IoC 컨테이너가 의존성을 주입하는 패턴이다. 비즈니스 로직의 변경에 유연하게 대처하기 위해서 스프링 프로젝트는 Web, Domain, Persistence 등 여러개의 Layer로 관심사 분리를 진행하는데, 각 Layer에서 하위 Layer에 속하는 인터페이스를 활용해서 클래스를 구현하고자 할 때, 해당 구현 클래스에 대한 의존성을 개발자가 직접 생성자 함수를 호출해서 주입하지 않고, Bean으로 등록된 클래스라면 IoC 컨테이너가 알아서 주입시켜주는 것이다.
public interface UserRepository {
void save(User user);
}
import org.springframework.stereotype.Repository;
@Repository
public class UserRepositoryImpl implements UserRepository {
public void save(User user) {
// 데이터베이스 저장 로직
System.out.println("저장 완료: " + user.getName());
}
}
예를 들면 위와 같이 DB 접근을 위한 UserRepository 인터페이스, UserRepositoryImpl 구현체가 있다고 하자.
그리고 아래와 같이 UserService 클래스는 UserRepository 인터페이스를 의존하는 상황이라면,
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void registerUser(User user) {
userRepository.save(user);
System.out.println("유저 등록 완료");
}
}
여기서 UserRepository의 의존성을 IoC 컨테이너가 대신 해주는 것이다! 쏘 신기...
모듈 단위 의존성을 주입할 때는 아래와 같이 @Configuration 어노테이션을 활용해서 여러개의 관련된 Bean들을 하나의 모듈로 그룹화 할 수 있다.
@Configuration
public class PaymentModule {
@Bean
public PaymentGateway paymentGateway() {
return new StripeGateway(); // 모듈별 구현체 지정
}
@Bean
public RefundProcessor refundProcessor() {
return new DefaultRefundProcessor();
}
}
한가지 주의할 점은, 위와 같이 각기 다른 타입의 빈이 여러개 있는 것은 괜찮지만, 같은 타입의 빈이 두 개 이상 있는 경우엔 NoUniqueBeanDefinitionException 예외가 발생할 수 있다. 이 경우에는 모듈에서 @Primary 어노테이션으로 우선순위를 지정해주거나, 의존성을 주입받는 클래스에서 @Qualifier 어노테이션으로 주입받을 Bean을 명시해줘야한다.
그리고 당연하지만 @Primary로 주입 우선순위가 높은 Bean이 정의되어있어도, @Qualifier로 지정하는 Bean의 우선순위가 더 높다.
다음으로는 Spring의 AOP 개념에 대해 클립을 수강하고 내용을 정리해보았다.
AOP는 관점 지향 프로그래밍이라는 뜻인데, 프로젝트의 비즈니스 로직과는 관련이 없이 공통적으로 도입될 필요가 있는 보안, 로깅, 캐싱, 트랜잭션 관리, 모니터링 등과 같은 로직을 작성하고, 횡단적으로 관심사를 분리해서 이를 중심으로 설계 또는 구현을 하는 프로그래밍 기법이다. Spring에서는 이를 한 곳으로 모아서 처리할 수 있도록 도와주는 기능인거같다.
프론트를 선행학습 했어서 그런지 재사용성을 극대화한 Headless Compoonent 등이 생각났는데, 이건 UI를 구성하는 과정에서의 Boilerplate 관점에서 봐야하고, AOP는 프로젝트에서 전역적으로 활용되는 공용 로직, 코어 모듈에 조금 더 관련이 깊어보이는 것 같았다.
AOP를 이야기할 때 사용하게 되는 Join Point(횡단 관심사가 실행되는 지점), Advice(Join Point에서 실행되는 코드), Pointcut(Join Point 중 Advice를 적용할 곳을 선별하는 표현식), Target(AOP 처리에 의해 처리 흐름에 변화가 생긴 객체) 등의 용어가 있었는데, 실제로 AOP를 적용해보면서 이해하는게 빠를 것 같다.
Advice는 또 Before, After Returning, After Throwing, After, Around 등 다양한 유형이 있고, 이 Advice들은 Spring에서 어노테이션으로 적용할 수 있다.
Spring에서 AOP가 실행되는 흐름을 알아보면 다음과 같다.
- Spring AOP는 Spring IoC 컨테이너에서 관리하는 Bean을 Target으로 Advice를 적용하는 기능 탑재.
- Advice가 적용된 Bean은 실제 의존성을 주입받는 곳에서는 Advice가 적용된 Proxy 객체의 의존성을 주입받음.
여기서 추가로 궁금해서 찾아본 부분은, Bean이 일반 클래스인 경우와 인터페이스를 구현한 클래스인 경우는 의존성 주입 여부가 달라지는데, Advice를 적용하는 흐름도 달라지지 않을까? 였어서 추가로 검색해보았다.
- Bean이 일반 클래스인 경우
- CGLIB 활용. 프록시 객체는 일반 클래스 기반의 객체를 상속한 서브 클래스를 생성해서 그걸 기반으로 만들어짐.
- ASM 라이브러리를 활용해서 바이트코드 조작을 통해 메서드 호출을 가로채서 AOP Advice 적용 후 원래 대상 객체의 메서드를 실행.
- Bean이 인터페이스를 구현하고 있는 경우
- JDK Dynamic Proxy 활용. 프록시 객체는 인터페이스를 구현한 익명 클래스를 기반으로 런타임에 만들어진 후, InvocationHandler를 활용해서 메서드 호출을 가로채고, AOP Advice를 적용한 후에 원래 대상 객체의 메서드를 실행.
- 공통적으로는 BeanPostProcessor의 구현체인 AnnotationAwareAspectJAutoProxyCreator(AAAPC)가
1) @Aspect가 붙은 Bean을 찾아 Advisor(Pointcut + Advice)로 변환하고,
2) Pointcut 조건에 맞는 Bean을 찾으면 해당 Bean의 프록시 객체를 생성하여 실제 의존성 주입 시 프록시 객체가 주입되도록 처리한다.
- 즉, IoC 컨테이너에는 원본 Bean이 등록되지만, AOP 적용 대상이 되는 경우에는 실제 의존성 주입 시 프록시 객체가 반환된다.
정리하면 Spring AOP는 Bean의 유형에 따라 프록시 생성 방식은 다르지만,
AOP Advice가 적용된 Bean은 `BeanPostProcessor(AAAPC)`에 의해 프록시 객체로 감싸지며,
IoC 컨테이너에서는 원본 Bean을 관리하지만 의존성 주입 시에는 프록시 객체가 주입된다.
학습 시작 인증
학습 종료 인증
첫 번째 클립 수강 인증
두 번째 클립 수강 인증
학습 인증 사진