본문 바로가기

Programming

자바 스프링 실무 꿀팁 모음 – 실전 예제 중심으로 배우는 생산성 향상 기술들

728x90
반응형

자바 스프링(Spring)은 대규모 백엔드 시스템을 구축하는 데 있어 가장 널리 쓰이는 프레임워크 중 하나입니다. 하지만 프로젝트가 커지고 코드가 복잡해질수록, 사소한 비효율이 쌓여 생산성을 저하시킬 수 있죠. 이번 포스트에서는 실무에서 자주 사용하는 꿀팁 10가지를 예제와 함께 소개합니다.


1. @Slf4j vs 수동 로그 선언

@Slf4j
@RestController
public class SampleController {

    @GetMapping("/test")
    public String testLog() {
        log.info("이건 logback 기반 로그입니다.");
        return "ok";
    }
}

왜 좋은가?
Lombok의 @Slf4j를 쓰면 LoggerFactory.getLogger() 선언을 생략할 수 있어 코드가 깔끔해짐. 실무에서는 로깅 실수를 줄이고, 일관성 있게 관리 가능.


2. 스프링 빈 등록 실수 방지용 – @ComponentScan(basePackages = "com.myapp")

@Configuration
@ComponentScan(basePackages = "com.myapp")
public class AppConfig {
}

주의할 점
하위 패키지를 스캔하지 못하면 의도치 않게 빈 주입이 안 되는 일이 생김. 명시적으로 basePackages를 지정해주는 것이 대규모 프로젝트에서 안전.


3. DTO 변환을 ModelMapper 또는 MapStruct로 자동화

// ModelMapper 사용 예시
ModelMapper modelMapper = new ModelMapper();
UserDTO userDTO = modelMapper.map(userEntity, UserDTO.class);

실무 팁
Controller → Service → Entity로 갈 때 DTO를 매번 수동으로 변환하는 것은 비효율적. MapStruct는 컴파일 타임에 코드를 생성해 성능까지 보장.


4. @Transactional(readOnly = true) 성능 최적화

@Transactional(readOnly = true)
public List<User> getAllUsers() {
    return userRepository.findAll();
}

효과
JPA의 dirty checking을 비활성화해서 읽기 전용 트랜잭션일 경우 DB 부하를 줄임. 특히 조회가 많은 페이지에선 필수.


5. @ExceptionHandler로 전역 예외 처리 통합

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MyCustomException.class)
    public ResponseEntity<?> handleCustomEx(MyCustomException ex) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage());
    }
}

장점
Controller마다 try-catch를 남발하지 않고, 예외 처리 로직을 중앙화할 수 있어 유지보수가 용이함.


6. @Value, @ConfigurationProperties 설정 값 관리 차이

@Value("${app.name}")
private String appName;

vs

@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private String version;
}

실무 팁
설정값이 많다면 @ConfigurationProperties를 통해 클래스로 묶는 것이 정리되고, 테스트하기도 쉬움.


7. Lazy Initialization으로 순환 참조 피하기

@RequiredArgsConstructor
@Service
public class OrderService {
    private final @Lazy PaymentService paymentService;
}

문제 해결
서로를 참조하는 서비스 간 순환참조 문제가 생길 때 @Lazy로 지연 로딩을 지정하면 런타임에 주입되므로 해결 가능.


8. RestTemplate 대신 WebClient로 비동기 HTTP 호출

WebClient client = WebClient.builder().baseUrl("https://api.example.com").build();

public Mono<String> getExternalData() {
    return client.get()
                 .uri("/data")
                 .retrieve()
                 .bodyToMono(String.class);
}

현대적인 방법
Spring WebFlux 기반의 WebClient는 비동기 처리와 성능 최적화에 강력. 특히 마이크로서비스 환경에 적합.


9. Profile 분기 처리로 환경별 설정 적용

# application-dev.yml
server:
  port: 8081

# application-prod.yml
server:
  port: 8082

(yaml)

@Profile("dev")
@Configuration
public class DevConfig {
}

현장 팁
테스트, 개발, 운영 환경에 따라 DB나 포트 등 설정을 다르게 가져가야 할 때 매우 유용.


10. 테스트 시 Embedded DB (H2) 적극 활용

@SpringBootTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY)
public class UserServiceTest {
}

이점
로컬 DB 환경을 복제하지 않아도 테스트 자동화 가능. CI/CD 파이프라인에서도 빠르게 검증 가능.

 

 

 

728x90
반응형