2025. 3. 10. 18:31ㆍBackEnd(Java)/Spring Boot
✅ 아래 내용들에 대해서 알아보자
- 스프링 컨테이너로 빈 관리를 안 하면?
스프링 컨테이너로 빈 관리를 안 하면?
스프링 컨테이너(Bean Factory 또는 ApplicationContext)에 등록된 빈(Bean)은 스프링의 생명주기 관리, 의존성 주입, 프락시 생성 등을 통해 다양한 기능을 활용할 수 있습니다. 반면, new로 생성한 객체는 스프링의 관리 범위 밖에 있으므로 아래와 같은 기능을 사용할 수 없습니다.
1. AOP (Aspect-Oriented Programming)
스프링의 AOP는 주로 프록시 패턴을 통해 구현됩니다. @Transactional, @Around, @Before 같은 AOP 기능은 스프링이 빈을 프록시 객체로 감싸서 제공합니다.
@TransactionalEventListener
- 동작:
- @TransactionalEventListener는 트랜잭션 상태(예: AFTER_COMMIT)에 따라 이벤트 처리를 지연시키거나 조건부로 실행합니다.
- 이를 위해 Spring은 트랜잭션 동기화 매니저(TransactionSynchronizationManager)와 연계하며, 메서드 호출을 프록시로 래핑합니다.
- 프록시 사용:
- @TransactionalEventListener가 붙은 메서드는 Spring AOP 프록시를 통해 트랜잭션 상태를 감지하고, 적절한 시점에 호출됩니다.
- 따라서 프록시 기반이라고 할 수 있습니다.
@Async
- 동작:
- @Async가 붙으면 메서드가 별도 스레드에서 비동기적으로 실행됩니다.
- Spring은 이를 위해 프록시를 생성해 비동기 호출을 처리합니다.
- 프록시 사용:
- @Async는 AOP 프록시를 통해 메서드 호출을 인터셉트하고, TaskExecutor로 작업을 위임합니다.
자기 참조 문제와 프록시
- 문제:
- 동일 클래스 내에서 @EventListener 메서드가 다른 @EventListener 메서드에서 발행된 이벤트를 처리하려면, Spring의 프록시를 거쳐야 합니다.
- 하지만 같은 객체 내에서 직접 메서드를 호출하면 프록시가 우회되어 @EventListener가 동작하지 않습니다.
- @Transcational 어노테이션도 동일함.
- 이유:
- Spring AOP는 프록시 기반으로 동작하며, 프록시는 빈 간 호출에서만 적용됩니다.
- 클래스 내부 호출(this.handleAnotherMethod())은 프록시를 거치지 않으므로 어노테이션(@Async, @Transactional 등)이 무시됩니다.
2. 트랜잭션 관리
트랜잭션 매니저(PlatformTransactionManager)는 스프링 빈에만 적용된다.
@Transactional은 AOP를 통해 트랜잭션 시작/커밋/롤백을 처리하므로, 스프링 DI로 관리되지 않는 객체에서는 동작하지 않습니다.
new로 생성한 객체는 데이터베이스 작업을 트랜잭션 없이 실행하거나, 호출 스택 상위의 트랜잭션에 의존하게 됩니다.
3. 의존성 주입 (DI)
@Autowired, @Inject 같은 의존성 주입은 스프링 컨테이너가 빈 간의 관계를 관리할 때만 동작합니다. 내부 필드에 @Autowired가 있어도 주입되지 않고 null로 남습니다.
4. 생명주기 관리
스프링은 빈의 생성(@PostConstruct), 소멸(@PreDestroy), 초기화 등을 관리합니다. new로 생성한 객체는 이러한 생명주기 콜백이 호출되지 않습니다.
5. 이벤트 처리
스프링의 이벤트 시스템(ApplicationEventPublisher, @EventListener)은 빈 간의 통신을 지원합니다. 스프링 DI로 관리되지 않는 객체는 이벤트를 발행하거나 수신할 수 없습니다.
6. 환경 설정 및 프로퍼티 주입
@Value로 환경 변수나 프로퍼티 파일 값을 주입받는 기능은 빈에만 적용됩니다. 스프링 DI로 관리되지 않는 객체는 @Value가 무시되어 기본값이나 null이 사용됩니다.
7. 캐싱 (@Cacheable, @CacheEvict)
스프링의 캐싱 추상화는 AOP를 통해 구현됩니다. 스프링 DI로 관리되지 않는 객체는 캐싱이 적용되지 않습니다.
8. 보안 (@PreAuthorize, @Secured)
스프링 시큐리티의 메서드 수준 보안도 AOP 기반입니다. 스프링 DI로 관리되지 않는 객체는 보안 설정이 무시됩니다.
결론
스프링의 DI로 관리되지 않는 객체는 스프링 내부 아키텍처(특히 AOP, 트랜잭션, 의존성 주입 등)를 활용할 수 없다. 왜냐하면 스프링이 프록시와 컨테이너를 통해 기능을 제공하는 방식 때문입니다.
'BackEnd(Java) > Spring Boot' 카테고리의 다른 글
JWT & OAuth 정리 (0) | 2023.06.01 |
---|---|
@Meta Annotation에 대해서 알아보자 (0) | 2023.02.24 |
스프링 IoC/DI 찍먹 (0) | 2023.02.24 |
스프링 이벤트 처리 (0) | 2023.01.20 |
Doesn't say anything about org.gradle.plugin.api-version (required '7.6') (0) | 2023.01.03 |