inblog logo
|
LifeLog, DevLog
    Spring

    알고 있어야할 어노테이션들 - 3

    설정 관련, 트랜잭션
    KYJTHEYJ's avatar
    KYJTHEYJ
    Dec 25, 2025
    알고 있어야할 어노테이션들 - 3
    Contents
    알고 있어야할 어노테이션들 - 3설정 관련트랜잭션 관련

    알고 있어야할 어노테이션들 - 3

    설정 관련

    @Configuration 과 @Bean

    설정 관련 클래스를 스프링 컨테이너에 선언할 때 사용

    @Configuration
    public class AppConfig {
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }
    
    // 이렇게 등록한 설정부는
    // Spring을 시작 -> @Configuration 이 붙은 클래스를 찾고
    // @Bean 이 붙은 메서드를 실행하고 반환 값을 컨테이너에 등록한다
    
    // 이렇게 @Bean 이 붙은 메서드를 통해 바로 객체를 꺼내 쓸 수 있다
    passwordEncoder pe1 = context.getBean(passwordEncoder.class);
    passwordEncoder pe2 = context.getBean(passwordEncoder.class);
    // pe1 과 pe2는 동일하다 (싱글톤 패턴)
    
    // 다른 곳에서 사용할 때는 @AutoWired 로 주입 가능
    • @Component와 차이점

      • 클래스를 가져다 등록할 때 사용 → @Component

      • 메서드의 반환 객체를 등록할 때 → @Bean

    @Value 와 @ConfigurationProperties

    설정 파일 내 값을 사용할 때 (값을 직접 꺼내 부여 또는 그룹으로 관리해서 부여)

    @Component
    public class AppInfo {
    
        @Value("${app.name:testing}")
        private String appName;
    }
    
    // application.yml
    // app.name: MyApp
    
    // application.yml 같은 설정 파일 내에 app.name의 값을 꺼내어 appName에 할당
    // 기본값을 사용하는 :, 없다면 testing
    @Component
    @ConfigurationProperties(prefix = "app")
    public class AppProperties {
        private String name;
        private String version;
    }
    
    // application.yml
    // app:
    //   name: MyApp
    //   version: 1.0.0
    
    // prefix 가 app 인 설정 그룹을 가져와서 그 안의 name과 version 을 값 사용

    트랜잭션 관련

    @Transactional

    메서드의 실행을 트랜잭션 안에서 관리

    @Service
    public class OrderService {
    
        @Transactional
        public Order createOrder(OrderRequest request) {
            // 1. 재고 감소
            productRepository.decreaseStock(productId, quantity);
    
            // 2. 주문 생성
            Order order = orderRepository.save(new Order(...));
    
            // 3. 포인트 적립
            pointRepository.addPoint(userId, points);
    
            return order;
        }
    }
    
    // 이러면 재고 감소, 주문 생성, 포인트 적립의 모든 실행이 전부 무사해야 커밋됨
    // 하나라도 실패시 전부 롤백
    // 이게 메서드 단위가 아니라 @Transactional 단위 임을 유의
    
    // 다만 UnChecked Exception만 걸러내주므로
    // Checked Exception이 발생해도 롤백해주려면
    // @Transactional(rollbackFor = Exception.class) 사용
    // 반대로 특정 Exception 은 허용시 (noRollbackFor = ..Exception.class)

    언급한 @Transactional 단위, 즉 전파의 단위도 설정할 수 있다

    // 1. REQUIRED (기본값) - 기존 트랜잭션에 참여
    @Transactional(propagation = Propagation.REQUIRED)
    
    // 2. REQUIRES_NEW - 새 트랜잭션 생성 (독립적)
    // -> 행동 로그, 에러 로그, 통계 데이터 등 메인 작업 실패시에도
    // 로그는 남아야할 경우에 사용
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    
    // 3. MANDATORY - 트랜잭션 필수 (없으면 예외)
    @Transactional(propagation = Propagation.MANDATORY)
    
    // 3-1. NEVER - 트랜잭션이 없는 상태에서만 실행
    @Transactional(propagation = PropagationNEVER)
    
    // 4. NOT_SUPPORTED - 트랜잭션 없이 실행
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    
    // 5. SUPPORTS - 부모 트랜잭션이 있으면 참여, 없으면 그냥 실행
    // -> READ-ONLY 메서드에 주로 사용
    @Transactional(propagation = Propagation.SUPPORTS)
    
    //-------------------------------------------------------
    
    @Service
    public class OrderService {
        
        @Autowired
        private EmailService emailService;
        
        @Transactional
        public Order createOrder() {
            // 주문 로직 (트랜잭션 O)
            Order order = orderRepository.save(...);
            
            // 이메일 발송 (트랜잭션 X)
            emailService.sendOrderEmail(order);
            
            return order;
        }
    }
    
    @Service
    public class EmailService {
        
        // 이메일은 트랜잭션 불필요
        @Transactional(propagation = Propagation.NOT_SUPPORTED)
        public void sendOrderEmail(Order order) {
            // 이메일 실패해도 주문은 유지됨
            emailClient.send(...);
        }
    }

    Share article
    Contents
    알고 있어야할 어노테이션들 - 3설정 관련트랜잭션 관련

    LifeLog, DevLog - https://github.com/KYJTHEYJ

    RSS·Powered by Inblog